@pollinations/ui 0.0.2 → 0.1.0-alpha.1

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 (59) hide show
  1. package/README.md +38 -71
  2. package/dist/{Chip-SM52sUbZ.d.cts → Chip-CQCq34kS.d.cts} +1 -1
  3. package/dist/{Chip-C5impfYd.d.ts → Chip-Cj4xG7Te.d.ts} +1 -1
  4. package/dist/app-user-menu/sdk.cjs +497 -0
  5. package/dist/app-user-menu/sdk.cjs.map +1 -0
  6. package/dist/app-user-menu/sdk.d.cts +18 -0
  7. package/dist/app-user-menu/sdk.d.ts +18 -0
  8. package/dist/app-user-menu/sdk.js +469 -0
  9. package/dist/app-user-menu/sdk.js.map +1 -0
  10. package/dist/app.css +94 -3
  11. package/dist/auth/index.cjs +77 -62
  12. package/dist/auth/index.cjs.map +1 -1
  13. package/dist/auth/index.js +77 -62
  14. package/dist/auth/index.js.map +1 -1
  15. package/dist/gen/index.cjs +477 -0
  16. package/dist/gen/index.cjs.map +1 -0
  17. package/dist/gen/index.d.cts +35 -0
  18. package/dist/gen/index.d.ts +35 -0
  19. package/dist/gen/index.js +451 -0
  20. package/dist/gen/index.js.map +1 -0
  21. package/dist/index.cjs +1875 -761
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +294 -109
  24. package/dist/index.d.ts +294 -109
  25. package/dist/index.js +1889 -798
  26. package/dist/index.js.map +1 -1
  27. package/dist/styles.css +1 -1
  28. package/dist/theme-jRPPBmld.d.cts +20 -0
  29. package/dist/theme-jRPPBmld.d.ts +20 -0
  30. package/dist/wallet/index.cjs +17 -8
  31. package/dist/wallet/index.cjs.map +1 -1
  32. package/dist/wallet/index.d.cts +2 -2
  33. package/dist/wallet/index.d.ts +2 -2
  34. package/dist/wallet/index.js +17 -8
  35. package/dist/wallet/index.js.map +1 -1
  36. package/package.json +15 -18
  37. package/dist/Button-Bn8pGg6N.d.ts +0 -26
  38. package/dist/Button-CWUBCiIc.d.cts +0 -26
  39. package/dist/auth/sdk.cjs +0 -220
  40. package/dist/auth/sdk.cjs.map +0 -1
  41. package/dist/auth/sdk.d.cts +0 -53
  42. package/dist/auth/sdk.d.ts +0 -53
  43. package/dist/auth/sdk.js +0 -187
  44. package/dist/auth/sdk.js.map +0 -1
  45. package/dist/modality/index.cjs +0 -83
  46. package/dist/modality/index.cjs.map +0 -1
  47. package/dist/modality/index.d.cts +0 -25
  48. package/dist/modality/index.d.ts +0 -25
  49. package/dist/modality/index.js +0 -56
  50. package/dist/modality/index.js.map +0 -1
  51. package/dist/theme-VMRlhqST.d.cts +0 -9
  52. package/dist/theme-VMRlhqST.d.ts +0 -9
  53. package/dist/wallet/sdk.cjs +0 -206
  54. package/dist/wallet/sdk.cjs.map +0 -1
  55. package/dist/wallet/sdk.d.cts +0 -33
  56. package/dist/wallet/sdk.d.ts +0 -33
  57. package/dist/wallet/sdk.js +0 -175
  58. package/dist/wallet/sdk.js.map +0 -1
  59. package/dist/wallet.css +0 -73
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,13 +17,23 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
33
  Alert: () => Alert,
34
+ AppHeader: () => AppHeader,
24
35
  AppIcon: () => AppIcon,
36
+ AudioIcon: () => AudioIcon,
25
37
  BeakerIcon: () => BeakerIcon,
26
38
  BookIcon: () => BookIcon,
27
39
  Button: () => Button,
@@ -31,6 +43,7 @@ __export(src_exports, {
31
43
  Chip: () => Chip,
32
44
  ClipboardIcon: () => ClipboardIcon,
33
45
  ClockIcon: () => ClockIcon,
46
+ CodeBlock: () => CodeBlock,
34
47
  Collapsible: () => Collapsible,
35
48
  CopyButton: () => CopyButton,
36
49
  Dialog: () => Dialog,
@@ -38,21 +51,31 @@ __export(src_exports, {
38
51
  DiscordIcon: () => DiscordIcon,
39
52
  DownloadIcon: () => DownloadIcon,
40
53
  Dropdown: () => Dropdown,
54
+ DropdownItem: () => DropdownItem,
41
55
  ExternalLinkButton: () => ExternalLinkButton,
42
56
  ExternalLinkIcon: () => ExternalLinkIcon,
43
57
  Field: () => import_field.Field,
58
+ FileUpload: () => FileUpload,
44
59
  GenApiIcon: () => GenApiIcon,
45
60
  GitHubIcon: () => GitHubIcon,
61
+ Heading: () => Heading,
46
62
  IconButton: () => IconButton,
47
63
  ImageIcon: () => ImageIcon,
48
64
  InfoTip: () => InfoTip,
65
+ InlineLink: () => InlineLink,
49
66
  Input: () => Input,
67
+ LinkCard: () => LinkCard,
50
68
  LockIcon: () => LockIcon,
51
69
  MailIcon: () => MailIcon,
70
+ Markdown: () => Markdown,
52
71
  McpIcon: () => McpIcon,
72
+ MediaPlaceholder: () => MediaPlaceholder,
53
73
  MenuIcon: () => MenuIcon,
54
74
  MultiSelect: () => MultiSelect,
75
+ NavItem: () => NavItem,
55
76
  PeriodPicker: () => PeriodPicker,
77
+ PlusIcon: () => PlusIcon,
78
+ Prose: () => Prose,
56
79
  ScrollArea: () => ScrollArea,
57
80
  Section: () => Section,
58
81
  Slider: () => Slider,
@@ -67,196 +90,118 @@ __export(src_exports, {
67
90
  TableHeaderCell: () => TableHeaderCell,
68
91
  TableRow: () => TableRow,
69
92
  TerminalIcon: () => TerminalIcon,
93
+ Text: () => Text,
94
+ Textarea: () => Textarea,
70
95
  TokensIcon: () => TokensIcon,
71
96
  Tooltip: () => Tooltip,
72
97
  TrendUpIcon: () => TrendUpIcon,
73
98
  WalletIcon: () => WalletIcon,
74
99
  XIcon: () => XIcon,
75
- cn: () => cn,
100
+ cn: () => cn2,
76
101
  currentPeriod: () => currentPeriod,
77
102
  getPeriodBucketKeys: () => getPeriodBucketKeys,
103
+ headingClassName: () => headingClassName,
78
104
  periodBucketKeyToDate: () => periodBucketKeyToDate,
105
+ textClassName: () => textClassName,
106
+ themePalette: () => themePalette,
79
107
  themes: () => themes,
80
108
  useScrollLock: () => useScrollLock
81
109
  });
82
110
  module.exports = __toCommonJS(src_exports);
83
111
 
84
- // src/lib/cn-app.ts
112
+ // src/lib/cn.ts
85
113
  var import_clsx = require("clsx");
86
114
  var import_tailwind_merge = require("tailwind-merge");
115
+ var twMerge = (0, import_tailwind_merge.extendTailwindMerge)({ prefix: "polli" });
87
116
  function cn(...inputs) {
88
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(...inputs));
117
+ return twMerge((0, import_clsx.clsx)(...inputs));
89
118
  }
90
119
 
91
- // src/lib/period.ts
92
- var MS_PER_DAY = 864e5;
93
- function startOfUtcDay(date = /* @__PURE__ */ new Date()) {
94
- return new Date(
95
- Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
96
- );
97
- }
98
- function addUtcDays(date, days) {
99
- const next = new Date(date);
100
- next.setUTCDate(next.getUTCDate() + days);
101
- return next;
102
- }
103
- function startOfUtcMonth(date) {
104
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
105
- }
106
- function addUtcMonths(date, months) {
107
- return new Date(
108
- Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
109
- );
110
- }
111
- function startOfUtcIsoWeek(date) {
112
- const day = date.getUTCDay() || 7;
113
- return addUtcDays(startOfUtcDay(date), 1 - day);
114
- }
115
- function getUtcIsoWeekPeriod(date) {
116
- const day = date.getUTCDay() || 7;
117
- const thursday = addUtcDays(startOfUtcDay(date), 4 - day);
118
- const isoYear = thursday.getUTCFullYear();
119
- const yearStart = new Date(Date.UTC(isoYear, 0, 1));
120
- const isoWeek = Math.ceil(
121
- ((thursday.getTime() - yearStart.getTime()) / MS_PER_DAY + 1) / 7
120
+ // src/primitives/Typography.tsx
121
+ var import_jsx_runtime = require("react/jsx-runtime");
122
+ var headingSizeClasses = {
123
+ display: "polli:font-heading polli:text-5xl polli:leading-none",
124
+ title: "polli:font-heading polli:text-4xl polli:leading-none",
125
+ section: "polli:font-subheading polli:text-2xl polli:leading-tight",
126
+ subsection: "polli:font-subheading polli:text-xl polli:leading-tight",
127
+ card: "polli:font-subheading polli:text-lg polli:leading-tight"
128
+ };
129
+ var textSizeClasses = {
130
+ body: "polli:text-base polli:leading-relaxed",
131
+ sm: "polli:text-sm polli:leading-6",
132
+ xs: "polli:text-xs polli:leading-normal",
133
+ micro: "polli:text-micro polli:leading-normal"
134
+ };
135
+ var textToneClasses = {
136
+ base: "polli:text-theme-text-base",
137
+ strong: "polli:text-theme-text-strong",
138
+ soft: "polli:text-theme-text-soft",
139
+ muted: "polli:text-theme-text-muted"
140
+ };
141
+ var textWeightClasses = {
142
+ normal: "polli:font-normal",
143
+ medium: "polli:font-medium",
144
+ semibold: "polli:font-semibold",
145
+ bold: "polli:font-bold"
146
+ };
147
+ function headingClassName(size, className) {
148
+ return cn(
149
+ "polli:break-words polli:text-theme-text-strong",
150
+ headingSizeClasses[size],
151
+ className
122
152
  );
123
- return `${isoYear}-W${String(isoWeek).padStart(2, "0")}`;
124
- }
125
- function formatUtcDatePeriod(date) {
126
- return date.toISOString().slice(0, 10);
127
- }
128
- function formatUtcHourPeriod(date) {
129
- return date.toISOString().slice(0, 13).replace("T", " ");
130
- }
131
- function formatUtcMonthPeriod(date) {
132
- return date.toISOString().slice(0, 7);
133
- }
134
- function periodFromDate(granularity, date = /* @__PURE__ */ new Date()) {
135
- if (granularity === "day") {
136
- return {
137
- granularity,
138
- period: formatUtcDatePeriod(startOfUtcDay(date))
139
- };
140
- }
141
- if (granularity === "week") {
142
- return { granularity, period: getUtcIsoWeekPeriod(date) };
143
- }
144
- return { granularity, period: formatUtcMonthPeriod(startOfUtcMonth(date)) };
145
- }
146
- function currentPeriod() {
147
- return periodFromDate("day");
148
153
  }
149
- function periodToWindow(selection) {
150
- if (selection.granularity === "day") {
151
- const start2 = /* @__PURE__ */ new Date(`${selection.period}T00:00:00.000Z`);
152
- return { start: start2, end: addUtcDays(start2, 1) };
153
- }
154
- if (selection.granularity === "week") {
155
- const [yearText2, weekText] = selection.period.split("-W");
156
- const isoYear = Number(yearText2);
157
- const isoWeek = Number(weekText);
158
- const jan4 = new Date(Date.UTC(isoYear, 0, 4));
159
- const start2 = addUtcDays(startOfUtcIsoWeek(jan4), (isoWeek - 1) * 7);
160
- return { start: start2, end: addUtcDays(start2, 7) };
161
- }
162
- const [yearText, monthText] = selection.period.split("-");
163
- const start = new Date(
164
- Date.UTC(Number(yearText), Number(monthText) - 1, 1)
154
+ function textClassName({
155
+ size,
156
+ tone,
157
+ weight,
158
+ className
159
+ }) {
160
+ return cn(
161
+ "polli:break-words polli:font-body",
162
+ textSizeClasses[size],
163
+ textToneClasses[tone],
164
+ textWeightClasses[weight],
165
+ className
165
166
  );
166
- return { start, end: addUtcMonths(start, 1) };
167
167
  }
168
- function formatPeriodLabel(selection) {
169
- const { start, end } = periodToWindow(selection);
170
- if (selection.granularity === "day") {
171
- const today = startOfUtcDay();
172
- const yesterday = addUtcDays(today, -1);
173
- if (start.getTime() === today.getTime()) return "Today";
174
- if (start.getTime() === yesterday.getTime()) return "Yesterday";
175
- return start.toLocaleDateString("en-US", {
176
- timeZone: "UTC",
177
- month: "short",
178
- day: "numeric",
179
- year: "numeric"
180
- });
181
- }
182
- if (selection.granularity === "week") {
183
- const weekEnd = addUtcDays(end, -1);
184
- return `${start.toLocaleDateString("en-US", {
185
- timeZone: "UTC",
186
- month: "short",
187
- day: "numeric"
188
- })} - ${weekEnd.toLocaleDateString("en-US", {
189
- timeZone: "UTC",
190
- month: "short",
191
- day: "numeric",
192
- year: "numeric"
193
- })}`;
194
- }
195
- return start.toLocaleDateString("en-US", {
196
- timeZone: "UTC",
197
- month: "long",
198
- year: "numeric"
199
- });
168
+ function Heading({
169
+ as,
170
+ size = "section",
171
+ className,
172
+ children,
173
+ ...rest
174
+ }) {
175
+ const Component = as || "h2";
176
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ...rest, className: headingClassName(size, className), children });
200
177
  }
201
- function getPeriodBucketKeys(selection) {
202
- const { start, end } = periodToWindow(selection);
203
- const bucketKeys = [];
204
- const cursor = new Date(start);
205
- if (selection.granularity === "day") {
206
- while (cursor < end) {
207
- bucketKeys.push(`${formatUtcHourPeriod(cursor)}:00:00`);
208
- cursor.setUTCHours(cursor.getUTCHours() + 1);
178
+ function Text({
179
+ as,
180
+ size = "body",
181
+ tone = "base",
182
+ weight = "normal",
183
+ className,
184
+ children,
185
+ ...rest
186
+ }) {
187
+ const Component = as || "p";
188
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
189
+ Component,
190
+ {
191
+ ...rest,
192
+ className: textClassName({ size, tone, weight, className }),
193
+ children
209
194
  }
210
- return bucketKeys;
211
- }
212
- while (cursor < end) {
213
- bucketKeys.push(formatUtcDatePeriod(cursor));
214
- cursor.setUTCDate(cursor.getUTCDate() + 1);
215
- }
216
- return bucketKeys;
217
- }
218
- function periodBucketKeyToDate(bucketKey, granularity) {
219
- if (granularity === "day") {
220
- return /* @__PURE__ */ new Date(`${bucketKey.replace(" ", "T")}.000Z`);
221
- }
222
- return /* @__PURE__ */ new Date(`${bucketKey}T00:00:00.000Z`);
223
- }
224
- function isPeriodSelectable(selection, minDate = /* @__PURE__ */ new Date(0), maxDate = startOfUtcDay()) {
225
- const { start, end } = periodToWindow(selection);
226
- return end > minDate && start <= maxDate;
227
- }
228
-
229
- // src/lib/use-scroll-lock.ts
230
- var import_react = require("react");
231
- function useScrollLock(enabled = true) {
232
- (0, import_react.useEffect)(() => {
233
- if (!enabled) return;
234
- const originalBody = document.body.style.overflow;
235
- const originalHtml = document.documentElement.style.overflow;
236
- document.body.style.overflow = "hidden";
237
- document.documentElement.style.overflow = "hidden";
238
- return () => {
239
- document.body.style.overflow = originalBody;
240
- document.documentElement.style.overflow = originalHtml;
241
- };
242
- }, [enabled]);
243
- }
244
-
245
- // src/lib/cn.ts
246
- var import_clsx2 = require("clsx");
247
- var import_tailwind_merge2 = require("tailwind-merge");
248
- var twMerge2 = (0, import_tailwind_merge2.extendTailwindMerge)({ prefix: "polli" });
249
- function cn2(...inputs) {
250
- return twMerge2((0, import_clsx2.clsx)(...inputs));
195
+ );
251
196
  }
252
197
 
253
- // src/primitives/Alert.tsx
254
- var import_jsx_runtime = require("react/jsx-runtime");
198
+ // src/compositions/Alert.tsx
199
+ var import_jsx_runtime2 = require("react/jsx-runtime");
255
200
  var intentClasses = {
256
- info: "polli:border-theme-border polli:bg-theme-bg-pale polli:text-theme-text-strong",
257
- success: "polli:border-intent-success-border polli:bg-intent-success-bg-light polli:text-intent-success-text",
258
- warning: "polli:border-intent-warning-border polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
259
- danger: "polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
201
+ info: "polli:bg-theme-bg-pale polli:text-theme-text-strong",
202
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
203
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
204
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
260
205
  };
261
206
  var Alert = ({
262
207
  intent = "info",
@@ -264,116 +209,290 @@ var Alert = ({
264
209
  className,
265
210
  children,
266
211
  ...rest
267
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
212
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
268
213
  "div",
269
214
  {
270
215
  ...rest,
271
216
  role: intent === "danger" ? "alert" : "status",
272
- className: cn2(
273
- "polli:rounded-xl polli:border polli:px-3 polli:py-2 polli:text-sm",
217
+ className: cn(
218
+ "polli:rounded-xl polli:px-3 polli:py-2 polli:text-sm",
274
219
  intentClasses[intent],
275
220
  className
276
221
  ),
277
222
  children: [
278
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "polli:mb-1 polli:text-xs polli:font-bold polli:uppercase polli:tracking-wide", children: title }),
279
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children })
223
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
224
+ Text,
225
+ {
226
+ as: "div",
227
+ size: "xs",
228
+ tone: "strong",
229
+ weight: "bold",
230
+ className: "polli:mb-1 polli:uppercase polli:tracking-wide",
231
+ children: title
232
+ }
233
+ ),
234
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children })
280
235
  ]
281
236
  }
282
237
  );
283
238
 
284
- // src/primitives/Button.tsx
285
- var import_jsx_runtime2 = require("react/jsx-runtime");
286
- var sizes = {
287
- small: "polli:px-2 polli:pt-0.5 polli:pb-1",
288
- medium: "polli:px-4 polli:pt-1.5 polli:pb-2",
289
- large: "polli:px-6 polli:py-3"
290
- };
291
- var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
292
- var intentClasses2 = {
293
- danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-[oklch(0.88_0.075_25)] polli:transition-colors"
294
- };
295
- var buttonClasses = ({
296
- theme: _theme,
297
- intent,
298
- size,
299
- className,
300
- disabled
301
- }) => {
302
- const colorClasses = intent ? intentClasses2[intent] : themeClasses;
303
- return cn2(
304
- "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:placeholder-green-950 polli:font-medium polli:leading-normal polli:box-border",
305
- disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
306
- colorClasses,
307
- sizes[size || "medium"],
308
- className
309
- );
239
+ // src/compositions/AppHeader.tsx
240
+ var import_react = require("react");
241
+
242
+ // src/assets/logo-wordmark.svg
243
+ var logo_wordmark_default = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="16.9 37.9 212.3 26.1" fill="currentColor"><defs><clipPath id="a"><path d="M16.969 37.434h27V64h-27Zm0 0"/></clipPath></defs><g clip-path="url(%23a)"><path d="M16.996 49.113c0-.195 0-.386.012-.597.137-.004.238-.024.234-.188-.004-.074.047-.094.113-.094h.528c.097 0 .16-.035.164-.144 0-.09.043-.125.133-.121q.058.006.117 0c.129-.004.277.039.308-.157a.06.06 0 0 1 .028-.023c.11-.039.21-.11.336-.098.097.008.164-.03.156-.144-.004-.086.04-.11.121-.11q.449 0 .899-.011c.175 0 .199-.02.203-.196.004-.417 0-.835 0-1.253 0-.997.004-1.993 0-2.989 0-.113.039-.156.152-.156.805.004 1.61 0 2.414 0q1.161.001 2.316-.004c.11 0 .172.024.16.149-.007.101.06.125.145.125q.358 0 .723.003c.101 0 .156-.042.16-.148 0-.055.008-.11.086-.125.187-.031.183-.035.187-.23 0-.051.004-.106-.003-.157-.008-.105.027-.16.14-.148.098.012.133-.04.133-.133-.004-.098.004-.195.004-.289.004-.078.035-.129.12-.121q.151.01.15-.137c-.005-.101.038-.144.14-.133.09.008.137-.035.129-.12-.008-.114.043-.153.148-.145.09.004.121-.047.121-.133-.003-.098.004-.195 0-.29q-.006-.114.11-.112.153-.007.3-.008c.083-.004.122-.043.126-.125v-.29c0-.085.03-.128.125-.124.086.008.168-.004.25.004.132.011.175-.051.168-.172-.004-.074.003-.149 0-.223-.008-.098.023-.148.132-.14.094.003.184-.012.278-.012.093.004.136-.047.14-.133 0-.09.004-.18 0-.266-.007-.097.024-.148.133-.136q.14.008.133-.133v-.211c.004-.184.004-.184.18-.188q.113-.001.226-.007c.082-.004.125-.043.125-.133-.004-.102 0-.203 0-.305 0-.07.031-.105.106-.102q.19 0 .379-.003c.082 0 .109.043.109.117-.004.09.004.183 0 .277-.008.106.043.149.148.145.09 0 .176.004.266.004.082 0 .117.035.117.12a4 4 0 0 0 0 .301c0 .067.028.121.098.114.168-.024.172.07.168.195-.004.367-.043.344.336.348.21 0 .21 0 .21.21.005.372-.034.329.333.333.199 0 .199 0 .203.195 0 .39-.004.332.336.34.207.004.207 0 .207.199 0 .063.004.125.004.188-.008.109.035.167.148.156.082-.008.13.02.117.113-.011.11.04.164.153.152.082-.007.125.032.12.114q-.007.169.161.156c.078-.004.11.039.11.113 0 .082.007.168.003.25-.008.113.032.18.157.172.082-.004.113.043.113.125-.004.09 0 .184 0 .277.004.09.043.141.136.137.098-.004.137.04.13.137-.008.09.03.137.128.137h.766c.078 0 .129-.032.129-.114-.004-.144.082-.156.2-.156l4.651.008c.188 0 .204.012.204.2-.004.401-.016.8-.008 1.198.008 1 .011 1.996 0 2.992 0 .165.023.196.187.196.297.004.59 0 .883 0 .09 0 .16.015.152.129-.004.093.051.133.141.133.086 0 .176.007.262.003.101-.007.152.028.136.133-.011.102.043.145.141.145.094-.004.184.004.277 0 .086-.008.137.023.13.117-.008.117.054.152.163.148.168-.004.332.004.5 0 .102-.004.149.028.145.13-.004.105.05.144.148.136q.048.001.094.008c0 .183 0 .37-.012.566-.203.02-.207.02-.242.211-.012.074-.058.078-.113.074-.113-.004-.156.055-.152.164.003.176 0 .352 0 .528 0 .078-.024.129-.114.125-.113-.008-.16.043-.156.156.004.055-.016.113-.086.105-.164-.011-.191.083-.184.215 0 .059-.007.121-.003.184.011.105-.028.16-.137.152-.098-.008-.133.043-.129.137 0 .094-.008.184 0 .277.004.09-.035.13-.125.121q-.148-.016-.145.137c.004.086-.027.137-.12.13-.11-.013-.153.042-.145.148.008.09-.035.128-.125.128-.106-.004-.149.051-.149.153 0 .074-.035.117-.113.113-.113-.004-.156.055-.156.16 0 .059-.016.102-.086.11-.188.027-.188.03-.188.222 0 .059-.004.121 0 .184.004.09-.023.144-.12.14-.102 0-.145.051-.145.149 0 .086-.047.121-.125.117-.11-.004-.153.047-.149.148 0 .09-.047.126-.132.122s-.168.004-.25 0c-.106-.004-.165.043-.157.148.004.094-.043.121-.129.117-.07-.004-.136.02-.132.094.011.176-.09.195-.223.184-.059-.008-.113.003-.172 0-.102-.004-.164.046-.16.148.004.094-.04.125-.125.121-.074-.004-.14.024-.137.106.012.156-.074.175-.195.164-.059-.004-.117.004-.172 0-.113-.012-.18.023-.172.152.004.082-.039.117-.121.113-.094-.004-.184 0-.277 0s-.157.04-.145.14c.008.114-.05.13-.144.13-.25-.008-.5-.004-.75-.008-.114 0-.18.039-.18.156 0 .098-.047.13-.14.13-.262-.005-.52 0-.778 0-.102-.005-.164.026-.164.136.004.097-.05.129-.14.129q-1.236-.006-2.466 0c-.109 0-.152-.043-.156-.145 0-.09-.05-.125-.137-.12q-.227 0-.46.003c-.07 0-.133.016-.133.105 0 .086.066.094.129.098.078.004.125.024.117.113-.008.114.043.176.164.168q.112-.01.113.106c0 .098.059.148.149.152.097 0 .128.047.125.137q0 .146.148.14c.094-.003.188.004.277.004.063 0 .11.02.11.086-.004.16.097.188.226.188.211 0 .422.004.633 0h1.45c.05.004.117-.02.132.07.035.196.04.196.242.196.051 0 .106.003.157 0q.146-.019.14.12c0 .098.04.153.14.145q.13-.011.122.113c-.004.102.035.16.144.157.079 0 .125.039.122.12-.008.106.046.153.152.15.078-.005.125.027.117.116-.008.11.05.153.148.153q.135-.001.122.133c-.004.062.007.14.09.132.195-.02.183.106.175.23-.004.052 0 .099 0 .15-.008.113.035.175.156.167.09-.004.118.04.114.133-.008.266 0 .535-.004.8-.004.114.043.153.148.15.094-.005.184 0 .278 0 .086-.005.129.03.125.124-.008.086 0 .176-.004.262-.004.102.027.164.14.156.082-.004.133.024.13.121-.005.094.038.153.14.149.086 0 .129.039.125.129-.008.097.047.148.144.144.098-.008.133.031.133.13v1.398c.004.086-.02.144-.125.136-.101-.008-.16.043-.156.149.008.093-.04.12-.125.113-.094-.004-.14.047-.137.137.004.105-.043.144-.14.14s-.133.051-.13.141c.009.086-.027.133-.12.129-.098-.008-.149.035-.145.137.004.097-.043.132-.137.132q-.696-.006-1.398 0c-.09 0-.14-.03-.137-.129q.012-.152-.14-.14c-.086.004-.133-.031-.125-.125.007-.102-.043-.145-.141-.145-.082.004-.133-.027-.125-.12.008-.106-.05-.16-.152-.153-.094.008-.125-.035-.125-.121q-.001-.149-.149-.145c-.094.004-.117-.047-.117-.129v-1.41c0-.097.035-.14.129-.136.11.007.156-.047.148-.153-.007-.082.032-.113.11-.11q.166.014.156-.155c-.004-.075.031-.118.11-.11.132.008.16-.062.16-.18 0-.37.003-.37.378-.363.11.004.157-.043.153-.144q-.001-.238.004-.477c0-.105-.047-.156-.153-.14q-.138.012-.125-.122c.008-.109-.047-.152-.148-.152-.074.004-.121-.031-.113-.11.007-.113-.043-.163-.153-.16-.078 0-.125-.027-.117-.117.008-.11-.047-.164-.156-.156-.086.004-.121-.039-.117-.121.004-.113-.055-.148-.164-.148-.172.003-.344 0-.516 0-.059 0-.125 0-.121-.083.012-.175-.098-.183-.23-.183q-.756.006-1.516 0c-.074 0-.16.008-.153-.11.008-.12-.062-.16-.171-.16-.16 0-.325-.007-.489 0-.101 0-.156-.035-.156-.144.004-.094-.05-.137-.14-.133s-.126-.031-.13-.121c-.003-.09-.058-.137-.144-.14-.086 0-.117-.04-.117-.122 0-.097-.051-.148-.145-.148s-.129-.047-.129-.13c-.004-.097-.05-.144-.152-.14-.078 0-.121-.039-.121-.12.004-.114-.055-.161-.16-.153-.082.004-.11-.04-.106-.113q.001-.142-.004-.278c-.004-.074-.035-.137-.113-.14-.086 0-.105.066-.105.14v3.942c0 .164.027.187.191.187.074-.004.152.004.227-.004.101-.008.128.04.12.133-.003.086.005.176.005.262 0 .093.039.144.136.136.094-.003.14.032.133.13-.004.097.04.148.14.144.087-.004.137.031.13.125-.012.101.039.144.136.144.086 0 .13.036.125.13v1.41c0 .081-.023.136-.117.128-.11-.007-.156.047-.148.153.008.082-.024.125-.114.113q-.168-.017-.16.152c.004.086-.035.133-.125.125-.105-.007-.16.04-.148.149.012.094-.031.129-.121.125-.094-.012-.14.039-.14.129.003.101-.04.136-.142.136a84 84 0 0 0-1.398 0c-.086 0-.133-.023-.125-.12.012-.102-.039-.157-.144-.15q-.135.006-.13-.124c0-.098-.046-.149-.144-.145-.086 0-.129-.039-.125-.129.008-.097-.039-.156-.14-.144-.098.008-.133-.035-.13-.133.004-.094-.046-.137-.136-.133-.102.004-.13-.047-.13-.136q.008-.7 0-1.399c0-.09.028-.144.126-.14.098.007.148-.04.14-.141q-.003-.128.122-.121c.113.004.156-.055.156-.16-.004-.059.016-.114.086-.106.176.016.176-.097.176-.219 0-.316.004-.316.308-.32.227 0 .235-.008.235-.226v-3.887c0-.082-.008-.16-.114-.16-.097 0-.105.078-.11.148 0 .09-.003.176 0 .266.005.082-.023.125-.112.113q-.16-.019-.157.145c.004.085-.03.14-.128.136-.106-.004-.153.051-.149.153 0 .05 0 .113-.066.109-.118-.004-.184.055-.235.152a.3.3 0 0 1-.133.106c-.066.035-.101.082-.097.156.004.098-.043.133-.137.125s-.14.04-.137.133c.008.12-.054.144-.164.14-.168-.007-.34 0-.511.004-.059 0-.133.012-.13.082.016.2-.109.192-.245.192-.493-.004-.985 0-1.477 0-.094-.004-.184.008-.176.133.004.109-.054.132-.148.132-.172-.003-.344 0-.516-.003-.101 0-.156.042-.152.148 0 .07-.016.121-.102.117-.12-.008-.172.055-.164.168.004.086-.039.106-.113.102-.106-.012-.16.035-.152.144.007.094-.04.133-.133.133q-.141-.005-.137.137c.004.101-.043.14-.144.133-.094-.008-.137.046-.137.136v.328c0 .293 0 .293.289.293.312.004.254 0 .262.254v.121c-.008.106.035.168.148.168.086 0 .133.04.129.125-.004.11.055.149.156.149.07-.004.11.027.106.101-.012.114.043.16.152.16.07 0 .117.028.117.11v1.45c0 .07-.027.12-.105.112-.114-.007-.164.043-.164.153 0 .078-.035.125-.121.117-.106-.012-.157.043-.153.144 0 .09-.035.137-.125.125-.113-.011-.148.047-.14.149.003.09-.04.129-.125.125q-.154-.012-.149.14c.004.094-.043.13-.137.13q-.696-.008-1.398 0c-.086 0-.137-.028-.129-.122.008-.117-.05-.156-.156-.152q-.118.007-.113-.11.01-.157-.149-.156c-.09 0-.121-.043-.117-.132 0-.098-.055-.149-.148-.145-.086.004-.122-.035-.125-.117 0-.098-.055-.145-.149-.145-.094.004-.121-.047-.121-.129q.006-.712 0-1.425c0-.082.035-.125.117-.121.106.007.152-.043.152-.145 0-.07.028-.121.11-.117.117.004.168-.055.164-.168 0-.067.031-.106.094-.098.164.012.172-.082.175-.207.004-.383-.07-.32.352-.336.16-.008.176-.012.188-.168.02-.254.003-.508-.004-.765 0-.09.02-.149.132-.145.102.004.153-.055.145-.16-.004-.082.004-.164 0-.25-.004-.09.023-.145.125-.137.11.012.148-.047.14-.148q-.005-.129.118-.117c.11.007.152-.047.148-.153q-.012-.123.117-.113c.106.012.157-.04.157-.145 0-.09.039-.14.132-.136.102.004.145-.051.141-.145-.008-.094.031-.129.121-.125.078.008.14-.027.137-.105-.004-.145.07-.172.191-.16.063.003.121 0 .184 0 .098-.004.164-.036.164-.145-.004-.094.047-.121.133-.121q.222.005.449.004a115 115 0 0 1 1.645 0c.082 0 .183.004.19-.098.017-.168.122-.18.247-.176.055 0 .105-.004.16-.004.094-.003.149-.05.153-.144 0-.09.043-.125.128-.129.094-.004.145-.055.141-.152 0-.075.035-.117.113-.114q.155.013.157-.144c0-.082.03-.133.125-.129.066 0 .136-.02.128-.11-.003-.09-.078-.101-.144-.101q-.224-.005-.45-.004c-.1-.004-.16.035-.152.145.004.086-.035.12-.117.117h-2.52c-.066 0-.109-.016-.105-.094.012-.137-.058-.172-.183-.172-.262.008-.52 0-.778 0-.086 0-.136-.031-.129-.12.008-.126-.054-.161-.168-.161-.253.004-.503-.004-.753.004-.102.004-.16-.02-.149-.137.012-.094-.039-.133-.133-.133-.093.004-.183-.004-.277.004-.098.004-.14-.035-.133-.129.004-.105-.05-.14-.148-.14-.086.004-.176 0-.262.004-.09.004-.133-.032-.125-.125.012-.106-.04-.153-.145-.149-.062 0-.128-.004-.125-.082.008-.164-.09-.191-.218-.187-.059.004-.121-.004-.184 0-.098.004-.152-.028-.144-.137q.015-.147-.137-.14c-.078.007-.133-.016-.125-.106.008-.125-.051-.168-.168-.156-.05.004-.09-.012-.106-.075-.05-.195-.054-.195-.254-.199h-.144c-.098.008-.152-.027-.145-.133.004-.062-.015-.125-.09-.12-.187.011-.187-.11-.18-.239.005-.047 0-.098.005-.145.004-.113-.043-.18-.156-.187-.075-.008-.11-.04-.11-.117.004-.094-.047-.137-.137-.133-.066 0-.128-.016-.132-.098-.008-.101-.043-.168-.145-.21-.058-.028-.098-.087-.129-.15a.17.17 0 0 0-.09-.089c-.086-.043-.164-.094-.195-.2-.012-.038-.047-.07-.086-.066-.156.016-.176-.074-.168-.195.004-.058-.004-.113-.004-.172.004-.105-.027-.183-.156-.176-.09.008-.121-.042-.117-.128.004-.09-.004-.176-.004-.266.004-.094-.035-.148-.137-.145-.086.004-.137-.027-.129-.12.008-.106-.047-.153-.152-.145-.086.008-.117-.035-.113-.117 0-.18-.004-.36 0-.54.004-.113-.04-.167-.153-.16-.066.004-.117-.007-.129-.093-.023-.184-.05-.196-.238-.153m13.75.067c0-.446.004-.89 0-1.332 0-.082.008-.153.113-.153.121 0 .157-.07.157-.18-.004-.171 0-.343 0-.515 0-.062.011-.113.09-.113.144 0 .18-.086.171-.207-.004-.059.004-.117 0-.172-.007-.102.02-.16.133-.164.098-.004.137-.067.137-.16l.004-.25c.004-.082.031-.133.125-.13.11.008.156-.054.148-.152-.008-.093.035-.113.117-.113.106 0 .157-.059.153-.168-.004-.078.004-.156 0-.234 0-.082.02-.137.117-.137.102 0 .156-.055.148-.156-.007-.094.036-.13.121-.13.094 0 .153-.034.145-.14-.004-.086.04-.12.121-.113.11.008.156-.05.152-.152-.003-.09.036-.13.125-.13.067 0 .137-.019.137-.093-.004-.184.117-.184.246-.176.047.004.094 0 .145 0 .074-.004.144-.023.144-.117 0-.086-.074-.102-.14-.102-.09.004-.117-.039-.114-.12.004-.094 0-.192 0-.29-.004-.054-.02-.12-.082-.113-.207.016-.195-.117-.187-.254.004-.055-.008-.105-.008-.16 0-.094-.039-.149-.14-.14-.083.003-.13-.024-.118-.114.016-.117-.035-.164-.148-.156-.078.008-.13-.028-.125-.114.004-.117-.051-.164-.168-.16-.078.004-.106-.039-.106-.117.004-.09-.004-.183 0-.277q.014-.16-.148-.145c-.09.012-.129-.023-.121-.117.012-.105-.035-.16-.145-.148-.086.007-.133-.036-.129-.121.004-.106-.039-.16-.148-.153-.086.004-.133-.035-.125-.125.012-.105-.047-.144-.14-.144-.098.004-.137-.043-.126-.137.008-.094-.035-.145-.132-.137-.102.008-.141-.039-.133-.14.008-.079-.028-.133-.114-.121-.152.015-.152-.07-.152-.184-.004-.387.067-.356-.379-.356-.086 0-.125.04-.125.13 0 .093-.004.19 0 .288.004.082-.031.125-.117.118-.117-.012-.156.046-.152.156q.009.116-.11.11c-.113-.013-.164.042-.152.152.008.09-.035.12-.117.113-.102-.004-.157.043-.153.152.004.086-.039.13-.128.121-.09-.004-.141.04-.141.133.004.106-.04.152-.149.145-.09-.012-.132.035-.125.125.008.109-.043.148-.148.14-.082-.008-.121.043-.117.121 0 .094-.004.184 0 .278.004.09-.028.144-.125.14-.098 0-.149.04-.145.145q.006.13-.129.125-.145-.006-.144.14c.004.094-.035.137-.133.133-.098-.008-.145.043-.14.14 0 .099-.005.196-.005.294 0 .055-.015.101-.078.098-.183-.008-.195.105-.183.242.004.05-.004.105 0 .156.008.105-.028.16-.14.152-.067-.004-.126.02-.126.102 0 .078.055.105.121.11.098.003.196.007.293.003.082 0 .125.028.117.117-.011.114.043.16.153.153.078 0 .129.03.125.117 0 .105.047.156.152.156q.123-.007.117.121-.004.136.133.137.151-.002.137.148c-.008.067.015.133.094.13.16-.016.183.07.168.199-.004.058.003.113.003.171 0 .11.04.18.16.172.083 0 .122.035.11.121-.012.118.047.164.156.157.082-.008.113.03.113.105q-.001.152.004.305c0 .062.02.125.094.12.18-.015.188.09.176.224-.004.062.004.12 0 .183q-.006.153.14.14c.106-.011.13.036.126.13-.004.168 0 .336.003.5 0 .078.012.164.11.168.144.004.156.082.156.199q-.006.722 0 1.449c0 .203.04.246.215.25.258.004.285-.023.285-.285zm-7.5-.094c-.047-.016-.062-.05-.058-.094.007-.14-.079-.168-.196-.164-.164.004-.332-.004-.5 0-.086 0-.133-.035-.125-.125.012-.121-.058-.156-.16-.156h-.45c-.1 0-.16.055-.16.152q.002.369.008.739c0 .093.047.148.145.144.113-.008.133.055.129.148-.004.172.004.344 0 .516-.004.106.035.156.144.149.09-.004.13.035.125.125-.003.093 0 .187 0 .277.004.062.02.133.09.129.188-.012.184.105.172.234 0 .05.004.098 0 .145q-.007.166.156.168c.09 0 .13.039.13.125q-.007.147.14.148c.086-.004.133.031.129.121q-.005.13.125.14c.078.013.129.052.137.134.007.105.066.152.164.148.09-.004.117.04.113.121-.004.102.047.156.152.149.09-.008.117.043.114.12-.004.098.039.153.14.145s.133.047.13.137c-.005.098.046.133.136.133.09-.004.176 0 .265 0 .082-.004.137.023.133.117-.004.105.055.148.156.148q.148-.004.29.004c.07 0 .109.032.105.102-.012.14.066.176.188.176.25-.004.5 0 .75-.004.085 0 .136.023.132.117-.004.129.075.148.18.148h2.215c.055 0 .105 0 .156-.027.035-.02.067-.043.067-.09 0-.05-.036-.086-.083-.086-.144-.004-.152-.097-.144-.207q.005-.1-.008-.195c-.004-.063-.031-.129-.094-.129-.187 0-.18-.117-.172-.246.004-.055 0-.106-.003-.16 0-.098-.043-.16-.149-.157q-.128 0-.12-.117c.003-.097-.048-.14-.138-.144-.097-.004-.14-.047-.144-.145s-.059-.148-.153-.14c-.085.004-.109-.036-.105-.11.004-.101-.05-.156-.152-.152-.082 0-.121-.04-.125-.121q-.007-.153-.16-.153c-.07-.003-.106-.035-.102-.105 0-.113-.059-.16-.164-.16-.067 0-.11-.031-.106-.106.008-.113-.043-.172-.16-.168q-.11.002-.11-.113.006-.17-.171-.164c-.04 0-.094-.004-.086-.055.02-.144-.062-.203-.18-.25-.03-.011-.074-.05-.078-.082-.027-.148-.133-.152-.25-.144-.054.004-.113-.004-.168 0-.097.004-.152-.028-.144-.133.004-.105-.055-.14-.153-.14-.086 0-.175-.005-.261 0-.086 0-.133-.036-.13-.13.005-.101-.042-.156-.152-.148q-.122.014-.12-.113c.007-.114-.06-.153-.165-.153-.168.004-.336-.004-.5.004-.093 0-.14-.031-.14-.129 0-.109-.067-.14-.164-.14-.098 0-.192-.004-.313-.008m16.137-.195c0-.055-.008-.106-.004-.16.012-.13-.047-.184-.176-.184-.144.004-.289 0-.433.004-.094 0-.153.039-.149.14.008.106-.047.141-.144.137l-.528.004c-.07 0-.14.016-.136.102.011.156-.079.171-.2.16-.054-.004-.113.004-.168 0-.113-.008-.183.031-.175.156.007.086-.036.113-.122.113-.171-.004-.347.004-.523.008-.098 0-.168.027-.16.14.004.098-.043.122-.133.114-.066-.004-.133.023-.133.098.008.183-.105.195-.238.183-.05-.004-.098.004-.145 0-.109-.004-.171.04-.168.153 0 .093-.05.12-.132.117-.086-.004-.168 0-.25 0-.098 0-.153.043-.153.14 0 .094-.043.133-.136.133-.09-.004-.141.055-.137.14 0 .099-.047.134-.137.134q-.146 0-.14.148.003.117-.11.117c-.101-.004-.156.04-.152.149q.007.121-.121.12c-.102-.003-.149.056-.153.153-.004.063-.023.113-.101.113-.098 0-.149.063-.16.157-.012.07-.04.113-.121.11-.11-.009-.16.05-.157.16 0 .073-.031.116-.11.112q-.146.002-.151.145c-.008.086-.043.125-.13.129-.085.008-.14.05-.144.144 0 .083-.031.125-.125.125-.11-.003-.156.063-.16.168 0 .079-.004.157 0 .239.008.09-.02.144-.121.14-.11-.004-.145.063-.145.16.004.055-.004.11.004.16.012.13 0 .239-.176.235-.046 0-.078.035-.082.086 0 .055.036.082.082.09q.07.014.145.015.353.005.71.004h1.5c.087 0 .192.004.2-.105.016-.149.106-.156.219-.16q.35 0 .7-.012c.1 0 .167-.04.163-.156 0-.078.043-.106.117-.106.102.004.203-.008.305-.008.063-.003.121-.027.117-.097-.008-.172.102-.176.223-.164.055.004.105-.004.16 0 .102 0 .16-.04.16-.149-.004-.086.043-.12.13-.125.085-.004.14-.054.14-.144s.043-.125.129-.121c.097.004.148-.055.144-.149-.004-.093.043-.125.13-.125.093.004.148-.043.14-.14 0-.078.043-.114.113-.121.105-.008.16-.06.152-.168q-.005-.114.114-.11c.101 0 .156-.05.156-.152 0-.094.055-.121.137-.113.101.007.144-.043.144-.141-.004-.09.004-.176 0-.266s.024-.144.121-.14c.09.004.125-.051.13-.133.007-.094.015-.192.015-.29 0-.073.027-.112.11-.112.12.003.155-.067.155-.176-.004-.168 0-.336 0-.504-.004-.082.02-.137.114-.133.12.004.16-.07.16-.18-.004-.16 0-.324 0-.511m-13.774-3.715c-.007-.106-.004-.196.145-.188.078.008.121-.047.121-.125q.005-.157.004-.316c-.004-.313.047-.317-.328-.317-.149 0-.297.012-.438-.046.032-.149-.035-.227-.187-.227h-3.149c-.14 0-.18.04-.18.18 0 .168.008.336.008.5l-.003 2.582c-.004.183.023.207.203.207q.377.005.754.004c.082 0 .136.02.132.117-.003.11.063.144.16.14l.278.004c.062 0 .105.02.101.09-.011.172.07.188.215.188h.739c.054 0 .113-.008.125.078.027.187.03.187.218.187.059 0 .114.004.172 0 .102-.011.16.024.145.137-.012.106.043.133.136.129.094 0 .192.004.29.004.078-.004.125.027.117.117-.008.113.05.156.156.152.066 0 .113.024.11.102-.008.129.062.16.179.164.32.008.324 0 .324-.328 0-.113-.043-.172-.152-.164-.11.008-.125-.05-.121-.137l-.004-.277c-.004-.063-.035-.117-.102-.113-.164.011-.168-.086-.168-.211zm13.77 1.629v-2.66c0-.165-.02-.188-.164-.188q-1.56.001-3.125-.004c-.113 0-.176.043-.172.16.004.106-.055.121-.14.121-.165-.004-.325.004-.489-.004-.133-.003-.184.055-.18.184.004.145.008.29.004.434 0 .097.04.152.14.144.099-.008.13.04.13.133q-.006 1.383 0 2.766c0 .086-.02.136-.121.125-.11-.012-.149.054-.149.152 0 .086-.004.168 0 .254.004.094-.035.14-.133.129-.109-.008-.132.05-.136.144-.024.36-.004.352.351.34.086-.004.137-.05.137-.133-.004-.109.055-.136.148-.136.063 0 .122-.028.114-.098-.008-.16.086-.176.21-.168.051.004.106-.004.157 0 .113.008.18-.031.18-.152q.006-.119.129-.114c.09.004.183 0 .277 0 .078 0 .14-.035.133-.125-.004-.125.062-.144.168-.14.234.004.472-.004.71 0 .126.004.204-.043.204-.18 0-.074.039-.102.11-.102q.14 0 .288-.003c.082 0 .14-.032.137-.121 0-.114.066-.137.164-.133h.684c.222-.004.234-.012.234-.227zm-5.66 1.312c.008-.062.047-.101.105-.12.11-.036.156-.114.153-.231v-2.57c0-.075-.012-.145-.106-.153-.105-.008-.105.074-.11.145 0 .082-.027.124-.116.113q-.178-.02-.157.16c.008.09-.023.133-.12.125-.118-.012-.157.05-.15.16.005.078-.003.156 0 .234.009.106-.042.145-.14.137-.09-.004-.176.004-.266 0-.101-.004-.144.047-.144.14v.306c0 .058-.023.101-.082.097-.172-.015-.195.086-.184.223.004.066-.004.133 0 .199.004.082-.03.121-.117.117-.117-.008-.148.063-.148.164.004.172 0 .344 0 .516.004.09-.028.144-.13.137-.1-.008-.14.047-.136.144.004.086-.004.176 0 .262.004.09-.027.133-.121.125q-.148-.011-.148.137c-.004.086-.012.168-.012.25-.008.722.02 1.441 0 2.164-.008.242.008.492.015.734.004.07.02.137.106.145.086.003.098-.059.105-.125.008-.055.024-.11.09-.106.168.012.184-.098.188-.219v-.187c-.004-.082.023-.133.117-.13.098.005.148-.05.148-.144 0-.09.043-.129.13-.132.105-.004.14-.07.14-.164.004-.09.004-.176.008-.266 0-.066.027-.11.101-.106.121.004.168-.058.172-.168 0-.066.035-.093.098-.097.12-.012.16-.09.164-.2q.005-.119.004-.238c0-.054.011-.101.074-.105.172-.008.188-.125.191-.258v-.184c0-.062.024-.101.094-.101.137 0 .176-.082.176-.207-.004-.235 0-.465.008-.723m-4.836-.265c-.035-.047-.031-.102-.031-.153v-.355c-.004-.074-.032-.145-.11-.14-.148.007-.168-.071-.156-.188.004-.063-.004-.121 0-.184 0-.105-.035-.172-.152-.168-.094.004-.122-.043-.118-.129.004-.097 0-.195-.003-.289q-.007-.129-.137-.129c-.094.004-.184-.004-.278.004-.09.004-.132-.027-.128-.121.003-.082 0-.164 0-.25.003-.102-.036-.164-.141-.16-.102.004-.129-.047-.125-.14.004-.075-.027-.134-.11-.134-.12 0-.18-.043-.171-.168.004-.07-.051-.101-.114-.101-.066-.004-.09.043-.097.101-.004.028-.008.051-.008.079-.004.867-.012 1.73.008 2.593.004.098.043.153.144.149.094-.008.117.039.117.129-.003.254.004.507 0 .761 0 .118.036.188.165.18q.121-.004.113.125-.004.141.004.29c0 .062.027.124.093.12.172-.008.176.098.168.219-.003.055 0 .105 0 .16 0 .102.036.172.153.164.086 0 .129.04.125.13 0 .07.023.144.105.14.153-.004.168.082.16.203-.007.05.004.105 0 .156-.004.117.036.188.164.188q.114 0 .11.117c-.004.11.05.164.16.152.082-.004.11.031.11.11 0 .097.007.19.015.289.008.082.047.132.133.136.074.004.125.028.133.11.003.039.023.07.062.074.047.008.074-.02.094-.059.047-.074.043-.16.043-.242q.005-1.33.004-2.66a3 3 0 0 0-.004-.277c-.004-.07-.035-.125-.11-.121-.148.003-.171-.083-.152-.196.04-.219-.047-.379-.238-.515m9.207 6.035c.12.008.219-.008.21-.168 0-.059.044-.082.102-.082.09.004.184 0 .274 0 .11.004.172-.04.164-.153-.004-.101.05-.129.137-.129.07 0 .132-.023.128-.101-.011-.16.083-.168.2-.16.054.004.113-.004.168-.004.113.008.18-.028.175-.153-.003-.074.024-.12.106-.117.113.012.16-.043.16-.152q.001-.121.125-.113c.106.004.156-.051.148-.153-.003-.09.043-.12.122-.117.113 0 .16-.05.152-.164-.004-.074.039-.113.113-.11.11.005.153-.046.149-.152 0-.07.035-.12.113-.113.129.012.172-.059.168-.176-.004-.05.012-.086.078-.097.188-.028.188-.028.188-.22 0-.058.003-.112 0-.171-.004-.094.023-.152.128-.148q.152.007.145-.145c0-.082.031-.133.125-.129q.136.007.137-.133c-.004-.09.035-.136.133-.132.097.003.144-.055.144-.149q.005-.142.004-.289c-.004-.055.012-.086.078-.094.188-.023.188-.027.188-.222 0-.055.003-.106 0-.16-.008-.114.023-.176.152-.165.078.004.11-.043.11-.117.003-.082-.048-.105-.118-.105-.094 0-.184-.004-.277 0s-.14-.028-.133-.13c.008-.1-.05-.14-.148-.136-.086.004-.176-.004-.262 0-.09.004-.145-.027-.137-.129.012-.117-.055-.152-.16-.152-.219 0-.438-.004-.656 0-.184 0-.207.023-.207.203q-.005.497-.004.988c0 .098-.016.176-.14.164-.106-.007-.138.059-.138.153.004.183 0 .367.004.554 0 .055-.008.098-.082.114-.187.03-.187.035-.187.222 0 .055-.004.114 0 .172.008.094-.028.149-.133.14-.098-.003-.137.044-.137.138 0 .093-.004.183 0 .277 0 .082-.023.125-.113.117q-.16-.019-.156.145c.004.093-.032.136-.133.125s-.14.046-.14.14q-.01.142-.005.278c.004.09-.03.132-.12.125-.098-.008-.153.03-.145.136.011.106-.035.14-.137.133-.086-.008-.133.035-.125.125.004.102-.035.145-.14.145-.079-.004-.137.03-.137.12.004.11-.04.16-.157.153-.054-.004-.113.02-.105.086.016.145-.047.195-.184.195-.07 0-.093.067-.086.13.008.062.055.073.106.07.05 0 .098-.004.168-.008m-15.938-1.024c-.039-.015-.05-.05-.047-.086.008-.129-.039-.191-.175-.175-.067.007-.094-.024-.094-.094.004-.098 0-.192 0-.29-.004-.097-.043-.16-.152-.156-.082.004-.122-.03-.118-.117.012-.11-.039-.168-.152-.156-.098.012-.125-.039-.121-.125q.004-.142-.004-.289c0-.066-.027-.121-.098-.113-.16.015-.18-.075-.171-.203.007-.055 0-.114.003-.172.004-.11-.043-.18-.16-.176-.09 0-.11-.043-.11-.125.005-.168 0-.34 0-.512 0-.101-.034-.172-.151-.168-.094.004-.125-.047-.122-.133v-1.082c0-.093-.039-.148-.14-.148-.254.004-.508 0-.766.004-.066 0-.129.027-.125.101.012.168-.09.188-.215.18-.058-.004-.117.004-.172 0-.101-.004-.164.035-.16.145.004.093-.043.125-.129.12q-.144-.004-.289.005c-.066.004-.105.043-.105.109-.004.066.031.11.094.105.172-.011.18.094.168.22-.004.05.004.105 0 .156-.008.109.03.171.148.167.09-.003.121.047.117.133-.008.086 0 .176-.004.262 0 .09.032.148.13.148.093 0 .128.055.144.137.008.082.05.133.14.125.102-.008.141.043.137.14-.004.063.012.126.086.126.172-.008.191.094.18.226-.004.055 0 .106 0 .16-.004.102.043.16.144.16.086 0 .133.024.125.122-.011.097.04.152.137.148.102-.004.145.043.14.14 0 .079.036.13.118.126.113-.004.148.05.144.152 0 .086.047.137.13.13.109-.009.155.03.148.14-.008.086.039.133.129.129.105-.008.14.039.132.14-.007.086.04.13.13.121.109-.008.152.043.148.149-.004.093.054.133.14.129h.29c.05 0 .109.011.101.074-.02.187.098.2.23.191.067 0 .133.012.2.004.086-.008.12.02.113.11-.012.117.05.171.164.16.078-.008.11.027.105.097-.007.141.067.18.188.168.055-.004.105 0 .16 0 .07 0 .14-.004.14-.097.005-.09-.05-.125-.132-.121-.09.004-.133-.032-.129-.125q.012-.146-.14-.145c-.079 0-.141-.023-.133-.117.004-.11-.043-.156-.153-.152-.07.003-.12-.028-.113-.106.012-.148-.082-.176-.223-.176m15.489 8.383c-.086.008-.102.07-.102.14.004.087-.035.134-.125.126-.117-.012-.156.054-.156.16 0 .074-.028.113-.11.11-.12-.009-.16.058-.156.171.004.063 0 .121.004.184.004.09.04.152.145.14.074-.004.12.02.117.102-.012.125.05.18.172.168.078-.004.117.027.11.11-.017.128.046.175.17.163q.08-.006.157 0c.117.008.172-.039.164-.16-.008-.074.02-.117.106-.113q.17.017.164-.16c-.004-.07.031-.11.105-.102.145.02.188-.055.172-.183-.004-.059 0-.118 0-.172.004-.106-.043-.16-.148-.149-.086.004-.137-.027-.133-.12.008-.106-.04-.153-.145-.15-.07.005-.129-.023-.12-.1.015-.153-.071-.177-.196-.169-.055.008-.113.004-.195.004m-7.38.04c-.023.034-.023.073-.019.112q.007.12-.11.114c-.124-.012-.163.047-.155.164.003.07-.032.11-.102.101-.133-.007-.172.063-.168.18.004.059.004.113 0 .172-.008.11.035.168.152.156.063-.008.121.004.114.086-.008.133.062.18.183.176.07 0 .094.039.086.101-.015.133.047.184.176.172a1 1 0 0 1 .172 0c.113.008.164-.039.156-.152-.008-.082.024-.121.113-.121.106.004.164-.047.157-.16-.004-.067.027-.114.097-.11.149.008.18-.074.168-.199-.004-.05-.004-.105-.004-.156.004-.094-.043-.145-.132-.14-.098.003-.141-.036-.133-.13.011-.093-.035-.144-.13-.136-.109.007-.152-.043-.148-.149 0-.062-.02-.117-.093-.12-.121-.005-.246-.028-.38.038m-7.32 1.285c.059.254.059.25.336.25.114-.004.18-.035.172-.16-.008-.074.024-.117.106-.113.12.008.18-.055.175-.172-.003-.078.043-.102.106-.098.117 0 .156-.066.16-.168v-.183c-.008-.094-.047-.153-.148-.145-.082.004-.125-.027-.125-.113q.008-.166-.16-.156c-.075.008-.122-.028-.114-.106.012-.133-.054-.172-.176-.16-.054.004-.113 0-.168 0-.101-.004-.152.035-.144.14 0 .075-.023.13-.113.126-.11-.004-.157.05-.157.16 0 .062-.023.113-.101.105-.14-.015-.176.067-.172.184 0 .05-.004.105-.004.156-.004.113.043.176.164.168.047-.004.113-.004.11.063-.016.18.109.191.253.222m.747-8.433c.042-.13.023-.172-.098-.18a2 2 0 0 0-.25-.004c-.063.004-.09.043-.094.106 0 .062.024.109.086.109.113.004.23.027.355-.031m13.813-.188c-.043.004-.09 0-.133.012-.058.012-.09.05-.086.113 0 .067.047.09.106.094.086.004.172 0 .261 0 .07-.004.098-.047.102-.113.004-.067-.04-.094-.098-.102-.043-.004-.086-.004-.152-.004m0 0"/></g><path d="M82.117 39.523c-.152.172-.191 2.747-.172 9.192l.059 8.945h4.773l.059-9.039c.039-7.113 0-9.078-.191-9.21-.438-.266-4.278-.192-4.528.112m7.621.117c-.21.4-.265 16.895-.054 17.696.093.398.187.418 2.441.418 1.969 0 2.371-.059 2.465-.305.21-.535.133-17.43-.074-17.828-.192-.324-.422-.363-2.391-.363-1.965 0-2.195.039-2.387.383m7.774-.27c-.075.078-.133.992-.133 2.024v1.867h4.793l-.055-1.965-.058-1.945-2.215-.055c-1.203-.02-2.254.02-2.332.074m50.312.152c-.156.172-.21.88-.172 1.965l.055 1.68h4.777l.055-1.793c.04-1.316-.02-1.852-.191-1.965-.133-.074-1.164-.152-2.27-.152-1.512 0-2.101.078-2.254.265m76.512-.152c-.074.078-.133.992-.133 2.024v1.867h4.793l-.055-1.965-.058-1.945-2.215-.055c-1.203-.02-2.254.02-2.332.074m-86.539 1.527c-.059.172-.117 1.145-.117 2.192v1.887h-.84c-.973 0-1.07.136-1.07 1.601 0 1.184.21 1.45 1.183 1.45h.727v2.042c0 1.145.058 2.899.132 3.907l.118 1.87h1.832l.058.895.055.918h5.54l.058-1.316c.039-.934-.02-1.375-.192-1.469-.133-.098-.781-.172-1.449-.172h-1.187l.039-3.3.058-3.278 1.336-.098 1.336-.093v-2.86l-1.336-.097-1.336-.094-.058-2.156-.055-2.133h-2.352c-1.984 0-2.386.054-2.48.304m-88.414 4.215c-.078.055-.137 4.04-.137 8.848 0 8.14.02 8.75.344 8.883.172.097 1.3.133 2.484.097l2.14-.058v-5.13h3.532c2.695 0 3.535-.058 3.555-.245.02-.117.035-.535.054-.899.02-.668.02-.668 1.032-.722l.996-.059v-8.906l-.594-.113a7.4 7.4 0 0 0-1.05-.114c-.419 0-.458-.078-.458-.86v-.858H55.38l-.059.707c-.054.726-.054.726-.953.78l-.918.06v-1.547h-1.97c-1.085 0-2.042.058-2.097.136m9.031 6.235v3.336l-2.023.058c-1.11.035-2.063.02-2.102-.02-.039-.038-.074-1.562-.074-3.394v-3.3h4.2Zm9.32-5.473c-.054.875-.074.914-.629.875a5.6 5.6 0 0 0-.992.059l-.441.078v8.941l1.012.059.996.054.054.918.059.895 4.91-.04 4.906-.054.059-.918.059-.894h2.082v-4.461c0-4.328-.02-4.485-.383-4.598-.211-.074-.668-.094-1.012-.055-.594.055-.613.036-.707-.8l-.098-.86-4.906-.058-4.91-.04Zm6.914 5.492v3.336h-4.007v-6.676h4.007Zm22.864-6.254c-.075.055-.133 2.934-.133 6.387v6.273l2.351-.058 2.329-.055.058-6.351.035-6.332h-2.25c-1.242 0-2.332.058-2.39.136m6.972 6.196.059 6.351h4.773l.059-4.824.04-4.809h4.007l.039 4.809.059 4.824h4.773l.059-5.379.039-5.379-.996-.054-1.012-.059-.055-.914-.058-.898-3.094.039-3.094.058-.059.703-.058.727h-1.89v-1.527h-3.63Zm17-4.864.055 1.489 3.785.058 3.781.035-.058.918-.059.895-3.148.097-3.153.094-.019.762v.766l-.973.054c-.824.04-.996.133-1.09.477-.152.555-.152 1.773 0 2.879l.133.879h1.832l.059.894.058.918 2.922.055 2.903.058v-1.562l.918.055c.898.058.898.058.953.761l.058.727h3.61V46.922l-.574-.133c-.305-.074-.649-.074-.743-.02-.441.29-.785-.132-.785-.953v-.84h-10.523Zm7.602 7.399v.86h-3.629v-1.716h3.629Zm18.621-8.637c-.055.133-.074 2.992-.055 6.352l.055 6.101h4.777V45.074l-2.351-.058c-1.778-.04-2.367.02-2.426.191m9.168 0a5.3 5.3 0 0 0-.133.914c-.058.668-.058.668-1.07.727l-.992.054.039 4.426.054 4.422.997.059.992.058.058.895.055.898 4.93.055 4.906.039v-1.906h2.101v-8.961h-.742c-1.207 0-1.36-.137-1.36-1.07v-.84h-4.866c-3.746 0-4.91.058-4.969.23m6.973 6.16v3.336h-4.012v-6.676h4.012Zm7.179-6.234c-.054.113-.035 8.406.059 11.894l.02.727h2.367c1.988 0 2.386-.059 2.484-.305.059-.172.113-2.347.113-4.863v-4.574l1.97.054 1.948.059.094 4.766.098 4.77h4.773V46.98l-.957-.094-.953-.098-.094-.855-.097-.86-3.094-.058-3.113-.04v1.528h-1.91v-1.527h-1.798c-.992 0-1.851.078-1.91.156m18.321.075a5 5 0 0 0-.137.914c-.055.668-.055.668-1.05.727l-1.013.054v1.891c0 1.027.059 2 .118 2.172.074.23.379.305 1.03.305h.934l.06.8.058.82 2.73.06 2.711.058v1.695h-3.57c-1.989 0-3.707.074-3.84.172-.172.094-.23.535-.191 1.469l.058 1.316h10.313l.058-.898.055-.895.996-.058.992-.059.059-1.617c.074-2.367.035-2.48-1.11-2.48h-.937l-.055-.821-.058-.8-2.77-.094-2.77-.098v-1.715l3.516-.059c1.95-.02 3.61-.113 3.723-.207.133-.117.191-.726.152-1.527l-.074-1.355h-4.95c-3.8 0-4.984.058-5.038.23m19.902 0c-.04.133-.04.8.035 1.488l.117 1.239 3.684.058 3.668.035v1.91h-6.3v1.715h-2.102v4.176l1.011.059.992.054.06.918.054.914 2.906-.058 2.902-.055.059-.726c.055-.707.074-.707.894-.707.825 0 .844 0 .899.707l.059.726 1.87.055 1.852.058V52.32c0-4.215-.055-5.433-.226-5.453-.137-.02-.594-.039-1.012-.058-.766-.02-.766-.02-.863-.875l-.094-.86-5.176-.058c-4.05-.04-5.215 0-5.289.191m7.504 8.637v.879l-1.758-.059-1.773-.055-.059-.535c-.113-1.011 0-1.086 1.871-1.086h1.719Zm7.449-2.477v6.387h4.719l.113-2.156a67 67 0 0 0 0-8.293l-.113-2.328h-4.719Zm-22.137 2.27c-.152.172-.21.894-.171 2.133l.058 1.89 2.063.055 2.062.058-.058-2.156-.055-2.152-1.836-.059c-1.414-.039-1.89.02-2.063.23m0 0"/></svg>';
244
+
245
+ // src/compositions/AppHeader.tsx
246
+ var import_jsx_runtime3 = require("react/jsx-runtime");
247
+ var brandWordmarkMaskUrl = `url('${logo_wordmark_default}')`;
248
+ var brandWordmarkMask = {
249
+ WebkitMaskImage: brandWordmarkMaskUrl,
250
+ WebkitMaskPosition: "center",
251
+ WebkitMaskRepeat: "no-repeat",
252
+ WebkitMaskSize: "contain",
253
+ maskImage: brandWordmarkMaskUrl,
254
+ maskPosition: "center",
255
+ maskRepeat: "no-repeat",
256
+ maskSize: "contain"
310
257
  };
311
- function Button({
312
- as,
258
+ function scrollTopFor(target) {
259
+ return target === window ? window.scrollY : target.scrollTop;
260
+ }
261
+ function AppHeader({
313
262
  children,
314
- theme,
315
- intent,
316
- size,
263
+ navLabel,
264
+ autoHide = false,
265
+ scrollTargetRef,
266
+ brandHref = "https://pollinations.ai",
267
+ brandLabel = "Pollinations",
317
268
  className,
318
- disabled,
319
- ...buttonProps
269
+ innerClassName,
270
+ navClassName
320
271
  }) {
321
- const Component = as || "button";
322
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
323
- Component,
272
+ const [hidden, setHidden] = (0, import_react.useState)(false);
273
+ (0, import_react.useEffect)(() => {
274
+ if (!autoHide || typeof window === "undefined") {
275
+ setHidden(false);
276
+ return;
277
+ }
278
+ const target = scrollTargetRef?.current ?? window;
279
+ let lastScrollTop = scrollTopFor(target);
280
+ let frameId = 0;
281
+ const handleScroll = () => {
282
+ if (frameId) return;
283
+ frameId = window.requestAnimationFrame(() => {
284
+ frameId = 0;
285
+ const nextScrollTop = scrollTopFor(target);
286
+ const delta = nextScrollTop - lastScrollTop;
287
+ if (nextScrollTop < 16) {
288
+ setHidden(false);
289
+ } else if (delta > 8) {
290
+ setHidden(true);
291
+ } else if (delta < -8) {
292
+ setHidden(false);
293
+ }
294
+ lastScrollTop = nextScrollTop;
295
+ });
296
+ };
297
+ target.addEventListener("scroll", handleScroll, { passive: true });
298
+ return () => {
299
+ if (frameId) window.cancelAnimationFrame(frameId);
300
+ target.removeEventListener("scroll", handleScroll);
301
+ };
302
+ }, [autoHide, scrollTargetRef]);
303
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
304
+ "header",
324
305
  {
325
- "data-theme": intent ? void 0 : theme,
326
- className: buttonClasses({
327
- theme,
328
- intent,
329
- size,
330
- className,
331
- disabled
332
- }),
333
- disabled,
334
- ...buttonProps,
335
- children
306
+ className: cn(
307
+ "polli:sticky polli:top-0 polli:z-30 polli:border-b polli:border-theme-border polli:bg-surface-white polli:py-4 polli:backdrop-blur",
308
+ "polli:transition-transform polli:duration-200 polli:ease-out",
309
+ autoHide && "polli:will-change-transform",
310
+ hidden ? "polli:-translate-y-full" : "polli:translate-y-0",
311
+ className
312
+ ),
313
+ onFocusCapture: () => setHidden(false),
314
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
315
+ "div",
316
+ {
317
+ className: cn(
318
+ "polli:mx-auto polli:flex polli:w-full polli:max-w-5xl polli:flex-col polli:gap-4 polli:px-4 polli:sm:flex-row polli:sm:items-center polli:sm:justify-between polli:sm:px-6",
319
+ innerClassName
320
+ ),
321
+ children: [
322
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
323
+ "a",
324
+ {
325
+ href: brandHref,
326
+ target: "_blank",
327
+ rel: "noopener noreferrer",
328
+ className: "polli:inline-flex polli:shrink-0 polli:items-center polli:text-theme-text-strong",
329
+ children: [
330
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "polli:sr-only", children: brandLabel }),
331
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
332
+ "span",
333
+ {
334
+ "aria-hidden": "true",
335
+ className: "polli:block polli:h-7 polli:w-[220px] polli:max-w-full polli:bg-current",
336
+ style: brandWordmarkMask
337
+ }
338
+ )
339
+ ]
340
+ }
341
+ ),
342
+ children ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
343
+ "nav",
344
+ {
345
+ "aria-label": navLabel,
346
+ className: cn(
347
+ "polli:flex polli:min-w-0 polli:flex-wrap polli:gap-2",
348
+ navClassName
349
+ ),
350
+ children
351
+ }
352
+ ) : null
353
+ ]
354
+ }
355
+ )
336
356
  }
337
357
  );
338
358
  }
339
359
 
340
- // src/primitives/ButtonGroup.tsx
341
- var import_jsx_runtime3 = require("react/jsx-runtime");
342
- var ButtonGroup = ({
343
- wrap = true,
344
- className,
345
- children,
346
- role = "group",
347
- ...rest
348
- }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
349
- "div",
350
- {
351
- ...rest,
352
- role,
353
- className: cn2(
354
- "polli:flex polli:min-w-0 polli:items-center polli:gap-1.5",
355
- wrap ? "polli:flex-wrap" : "polli:flex-nowrap",
356
- className
357
- ),
358
- children
359
- }
360
- );
361
-
362
- // src/primitives/ChevronIcon.tsx
360
+ // src/primitives/ScrollArea.tsx
361
+ var import_react2 = require("react");
363
362
  var import_jsx_runtime4 = require("react/jsx-runtime");
364
- var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
363
+ var axisClasses = {
364
+ y: "polli:overflow-y-auto polli:overflow-x-hidden",
365
+ x: "polli:overflow-x-auto polli:overflow-y-hidden"
366
+ };
367
+ function assignRef(ref, value) {
368
+ if (typeof ref === "function") ref(value);
369
+ else if (ref) ref.current = value;
370
+ }
371
+ var ScrollArea = (0, import_react2.forwardRef)(
372
+ ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
373
+ const innerRef = (0, import_react2.useRef)(null);
374
+ const setRef = (0, import_react2.useCallback)(
375
+ (node) => {
376
+ innerRef.current = node;
377
+ assignRef(externalRef, node);
378
+ },
379
+ [externalRef]
380
+ );
381
+ (0, import_react2.useEffect)(() => {
382
+ const element = innerRef.current;
383
+ if (!element) return;
384
+ let hideTimer = null;
385
+ const clearHideTimer = () => {
386
+ if (hideTimer !== null) {
387
+ window.clearTimeout(hideTimer);
388
+ hideTimer = null;
389
+ }
390
+ };
391
+ const show = () => {
392
+ element.dataset.scrollbarActive = "true";
393
+ clearHideTimer();
394
+ };
395
+ const hide = () => {
396
+ element.dataset.scrollbarActive = "false";
397
+ clearHideTimer();
398
+ };
399
+ const scheduleHide = () => {
400
+ clearHideTimer();
401
+ hideTimer = window.setTimeout(hide, 2e3);
402
+ };
403
+ const handleInteraction = () => {
404
+ show();
405
+ scheduleHide();
406
+ };
407
+ hide();
408
+ element.addEventListener("scroll", handleInteraction, {
409
+ passive: true
410
+ });
411
+ element.addEventListener("wheel", handleInteraction, {
412
+ passive: true
413
+ });
414
+ element.addEventListener("touchstart", handleInteraction, {
415
+ passive: true
416
+ });
417
+ element.addEventListener("pointerdown", handleInteraction);
418
+ element.addEventListener("keydown", handleInteraction);
419
+ element.addEventListener("focusin", handleInteraction);
420
+ element.addEventListener("focusout", scheduleHide);
421
+ return () => {
422
+ clearHideTimer();
423
+ element.removeEventListener("scroll", handleInteraction);
424
+ element.removeEventListener("wheel", handleInteraction);
425
+ element.removeEventListener("touchstart", handleInteraction);
426
+ element.removeEventListener("pointerdown", handleInteraction);
427
+ element.removeEventListener("keydown", handleInteraction);
428
+ element.removeEventListener("focusin", handleInteraction);
429
+ element.removeEventListener("focusout", scheduleHide);
430
+ };
431
+ }, []);
432
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
433
+ "div",
434
+ {
435
+ ...rest,
436
+ ref: setRef,
437
+ "data-theme": theme,
438
+ className: cn(
439
+ "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
440
+ axisClasses[axis],
441
+ className
442
+ ),
443
+ children
444
+ }
445
+ );
446
+ }
447
+ );
448
+ ScrollArea.displayName = "ScrollArea";
449
+
450
+ // src/compositions/CodeBlock.tsx
451
+ var import_jsx_runtime5 = require("react/jsx-runtime");
452
+ var CodeBlock = ({
453
+ code,
454
+ theme,
455
+ codeClassName,
456
+ className,
457
+ ...rest
458
+ }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
459
+ ScrollArea,
460
+ {
461
+ ...rest,
462
+ theme,
463
+ axis: "x",
464
+ className: cn(
465
+ "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale",
466
+ className
467
+ ),
468
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
469
+ "pre",
470
+ {
471
+ className: cn(
472
+ "polli:p-4 polli:font-mono polli:text-xs polli:leading-6 polli:text-theme-text-strong",
473
+ codeClassName
474
+ ),
475
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: code })
476
+ }
477
+ )
478
+ }
479
+ );
480
+
481
+ // src/primitives/ChevronIcon.tsx
482
+ var import_jsx_runtime6 = require("react/jsx-runtime");
483
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
365
484
  "svg",
366
485
  {
367
486
  "aria-hidden": "true",
368
487
  width: "12",
369
488
  height: "12",
370
489
  viewBox: "0 0 12 12",
371
- className: cn2(
490
+ className: cn(
372
491
  "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
373
492
  expanded && "polli:rotate-180",
374
493
  className
375
494
  ),
376
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
495
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
377
496
  "path",
378
497
  {
379
498
  d: "M3 4.5 6 7.5l3-3",
@@ -387,48 +506,8 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_ru
387
506
  }
388
507
  );
389
508
 
390
- // src/primitives/Chip.tsx
391
- var import_jsx_runtime5 = require("react/jsx-runtime");
392
- var chipSizes = {
393
- sm: "polli:px-2 polli:py-0.5 polli:text-xs",
394
- md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
395
- lg: "polli:px-3 polli:py-1 polli:text-sm"
396
- };
397
- var intentClasses3 = {
398
- news: "polli:bg-[oklch(0.935_0.06_158)] polli:text-[oklch(0.46_0.13_158)]",
399
- alpha: "polli:bg-[oklch(0.93_0.06_300)] polli:text-[oklch(0.42_0.18_300)]",
400
- neutral: "polli:border polli:border-gray-400/70 polli:bg-gray-100/80 polli:text-gray-900",
401
- success: "polli:border polli:border-intent-success-border polli:bg-intent-success-bg-light polli:text-intent-success-text",
402
- warning: "polli:border polli:border-intent-warning-border polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
403
- danger: "polli:border polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
404
- };
405
- var Chip = ({
406
- theme,
407
- intent,
408
- size = "md",
409
- className,
410
- children,
411
- ...rest
412
- }) => {
413
- const intentClass = intent ? intentClasses3[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
414
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
415
- "span",
416
- {
417
- ...rest,
418
- "data-theme": theme,
419
- className: cn2(
420
- "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
421
- chipSizes[size],
422
- intentClass,
423
- className
424
- ),
425
- children
426
- }
427
- );
428
- };
429
-
430
- // src/primitives/Collapsible.tsx
431
- var import_jsx_runtime6 = require("react/jsx-runtime");
509
+ // src/compositions/Collapsible.tsx
510
+ var import_jsx_runtime7 = require("react/jsx-runtime");
432
511
  var Collapsible = ({
433
512
  label,
434
513
  expanded,
@@ -440,16 +519,16 @@ var Collapsible = ({
440
519
  focusClassName,
441
520
  panelClassName = "polli:border-t polli:border-theme-border polli:px-3 polli:pt-3 polli:pb-3",
442
521
  ariaLabel
443
- }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
522
+ }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
444
523
  "div",
445
524
  {
446
- className: cn2(
525
+ className: cn(
447
526
  "polli:rounded-lg polli:border polli:transition-all",
448
527
  wrapperClassName,
449
528
  disabled && "polli:opacity-50"
450
529
  ),
451
530
  children: [
452
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
531
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
453
532
  "button",
454
533
  {
455
534
  type: "button",
@@ -457,16 +536,16 @@ var Collapsible = ({
457
536
  "aria-label": ariaLabel,
458
537
  disabled,
459
538
  onClick: onToggle,
460
- className: cn2(
461
- "polli:w-full polli:flex polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:transition-colors",
539
+ className: cn(
540
+ "polli-control polli:w-full polli:flex polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:transition-colors",
462
541
  expanded ? "polli:rounded-t-lg" : "polli:rounded-lg",
463
542
  !disabled && hoverClassName,
464
543
  focusClassName,
465
544
  disabled ? "polli:cursor-not-allowed" : "polli:cursor-pointer"
466
545
  ),
467
546
  children: [
468
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "polli:flex-1 polli:min-w-0", children: label }),
469
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
547
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "polli:flex-1 polli:min-w-0", children: label }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
470
549
  ChevronIcon,
471
550
  {
472
551
  expanded,
@@ -476,17 +555,17 @@ var Collapsible = ({
476
555
  ]
477
556
  }
478
557
  ),
479
- expanded && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: panelClassName, children })
558
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: panelClassName, children })
480
559
  ]
481
560
  }
482
561
  );
483
562
 
484
- // src/primitives/CopyButton.tsx
485
- var import_react3 = require("react");
563
+ // src/compositions/CopyButton.tsx
564
+ var import_react4 = require("react");
486
565
 
487
566
  // src/primitives/Tooltip.tsx
488
- var import_react2 = require("react");
489
- var import_jsx_runtime7 = require("react/jsx-runtime");
567
+ var import_react3 = require("react");
568
+ var import_jsx_runtime8 = require("react/jsx-runtime");
490
569
  var TOOLTIP_MAX_WIDTH = 288;
491
570
  var TOOLTIP_VIEWPORT_MARGIN = 12;
492
571
  var Tooltip = ({
@@ -499,13 +578,13 @@ var Tooltip = ({
499
578
  triggerAs = "button",
500
579
  displayContents = false
501
580
  }) => {
502
- const [showTooltip, setShowTooltip] = (0, import_react2.useState)(false);
503
- const [tooltipPosition, setTooltipPosition] = (0, import_react2.useState)({
581
+ const [showTooltip, setShowTooltip] = (0, import_react3.useState)(false);
582
+ const [tooltipPosition, setTooltipPosition] = (0, import_react3.useState)({
504
583
  top: 0,
505
584
  left: 0,
506
585
  maxWidth: TOOLTIP_MAX_WIDTH
507
586
  });
508
- const triggerRef = (0, import_react2.useRef)(null);
587
+ const triggerRef = (0, import_react3.useRef)(null);
509
588
  const updateTooltipPosition = () => {
510
589
  if (triggerRef.current) {
511
590
  const rect = triggerRef.current.getBoundingClientRect();
@@ -527,15 +606,15 @@ var Tooltip = ({
527
606
  });
528
607
  }
529
608
  };
530
- const triggerClassName = cn2(
531
- "polli:relative polli:cursor-help polli:text-left polli:inline-flex polli:items-center",
609
+ const triggerClassName = cn(
610
+ "polli-control polli:relative polli:cursor-help polli:text-left polli:inline-flex polli:items-center",
532
611
  className
533
612
  );
534
613
  const cursorClass = displayContents ? "polli:contents" : "polli:cursor-help";
535
614
  const popupClasses = "polli:fixed polli:w-max polli:px-2 polli:py-1 polli:bg-theme-bg-pale polli:text-theme-text-strong polli:border polli:border-theme-border polli:text-xs polli:rounded-md polli:shadow-sm polli:z-50 polli:pointer-events-none polli:transition-opacity polli:whitespace-pre-line polli:break-words";
536
- const contentNode = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
537
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cursorClass, children }),
538
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
615
+ const contentNode = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
616
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: cursorClass, children }),
617
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
539
618
  "span",
540
619
  {
541
620
  style: {
@@ -570,7 +649,7 @@ var Tooltip = ({
570
649
  style
571
650
  };
572
651
  if (triggerAs === "span") {
573
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
652
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
574
653
  "span",
575
654
  {
576
655
  ref: (node) => {
@@ -581,7 +660,7 @@ var Tooltip = ({
581
660
  }
582
661
  );
583
662
  }
584
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
663
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
585
664
  "button",
586
665
  {
587
666
  ref: (node) => {
@@ -599,8 +678,8 @@ var Tooltip = ({
599
678
  );
600
679
  };
601
680
 
602
- // src/primitives/CopyButton.tsx
603
- var import_jsx_runtime8 = require("react/jsx-runtime");
681
+ // src/compositions/CopyButton.tsx
682
+ var import_jsx_runtime9 = require("react/jsx-runtime");
604
683
  function CopyButton({
605
684
  value,
606
685
  children,
@@ -613,9 +692,9 @@ function CopyButton({
613
692
  onCopyError,
614
693
  ...buttonProps
615
694
  }) {
616
- const [copied, setCopied] = (0, import_react3.useState)(false);
617
- const timeoutRef = (0, import_react3.useRef)(null);
618
- (0, import_react3.useEffect)(
695
+ const [copied, setCopied] = (0, import_react4.useState)(false);
696
+ const timeoutRef = (0, import_react4.useRef)(null);
697
+ (0, import_react4.useEffect)(
619
698
  () => () => {
620
699
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
621
700
  },
@@ -637,19 +716,20 @@ function CopyButton({
637
716
  onCopyError?.(error);
638
717
  }
639
718
  }
640
- const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
719
+ const button = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
641
720
  "button",
642
721
  {
643
722
  ...buttonProps,
644
723
  type: "button",
645
724
  onClick: handleCopy,
646
- className: cn2(
725
+ className: cn(
726
+ "polli-control",
647
727
  typeof className === "function" ? className(copied) : className
648
728
  ),
649
729
  children: typeof children === "function" ? children(copied) : children
650
730
  }
651
731
  );
652
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
732
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
653
733
  Tooltip,
654
734
  {
655
735
  triggerAs: "span",
@@ -660,148 +740,64 @@ function CopyButton({
660
740
  );
661
741
  }
662
742
 
663
- // src/primitives/Dialog.tsx
664
- var import_dialog = require("@ark-ui/react/dialog");
665
- var import_portal = require("@ark-ui/react/portal");
666
- var import_jsx_runtime9 = require("react/jsx-runtime");
667
- var sizeClasses = {
668
- sm: "polli:max-w-md",
669
- md: "polli:max-w-xl",
670
- lg: "polli:max-w-2xl"
671
- };
672
- var Dialog = ({
673
- open,
674
- onOpenChange,
675
- trigger,
676
- triggerAsChild = false,
677
- triggerClassName,
678
- title,
679
- titleClassName,
680
- ariaLabel,
681
- labelledBy,
682
- theme = "blue",
683
- size = "md",
684
- showBackdrop = true,
685
- backdropClassName,
686
- positionerClassName,
687
- contentClassName,
688
- children
689
- }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
690
- import_dialog.Dialog.Root,
691
- {
692
- open,
693
- onOpenChange: (details) => onOpenChange?.(details.open),
694
- children: [
695
- trigger && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
696
- import_dialog.Dialog.Trigger,
697
- {
698
- asChild: triggerAsChild,
699
- className: triggerClassName,
700
- children: trigger
701
- }
702
- ),
703
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_portal.Portal, { children: [
704
- showBackdrop && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
705
- import_dialog.Dialog.Backdrop,
706
- {
707
- className: cn2(
708
- "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
709
- backdropClassName
710
- )
711
- }
712
- ),
713
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
714
- import_dialog.Dialog.Positioner,
715
- {
716
- className: cn2(
717
- "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
718
- positionerClassName
719
- ),
720
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
721
- import_dialog.Dialog.Content,
722
- {
723
- "data-theme": theme,
724
- "aria-label": ariaLabel,
725
- "aria-labelledby": labelledBy,
726
- className: cn2(
727
- "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg",
728
- sizeClasses[size],
729
- contentClassName
730
- ),
731
- children: [
732
- title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
733
- DialogTitle,
734
- {
735
- className: cn2(
736
- "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
737
- titleClassName
738
- ),
739
- children: title
740
- }
741
- ),
742
- children
743
- ]
744
- }
745
- )
746
- }
747
- )
748
- ] })
749
- ]
750
- }
751
- );
752
- var DialogTitle = import_dialog.Dialog.Title;
753
-
754
- // src/primitives/Dropdown.tsx
755
- var import_popover = require("@ark-ui/react/popover");
756
- var import_portal2 = require("@ark-ui/react/portal");
757
- var import_react4 = require("react");
743
+ // src/primitives/Button.tsx
758
744
  var import_jsx_runtime10 = require("react/jsx-runtime");
759
- var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-surface-white polli:shadow-lg";
760
- var Dropdown = ({
761
- theme,
762
- trigger,
763
- children,
764
- align = "start",
765
- open: openProp,
766
- onOpenChange,
767
- panelClassName,
768
- className
745
+ var sizes = {
746
+ sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
747
+ md: "polli:px-4 polli:pt-1.5 polli:pb-2",
748
+ lg: "polli:px-6 polli:py-3"
749
+ };
750
+ var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
751
+ var intentClasses2 = {
752
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:transition-colors"
753
+ };
754
+ var buttonClasses = ({
755
+ theme: _theme,
756
+ intent,
757
+ size,
758
+ className,
759
+ disabled
769
760
  }) => {
770
- const [internalOpen, setInternalOpen] = (0, import_react4.useState)(false);
771
- const isControlled = openProp !== void 0;
772
- const open = isControlled ? openProp : internalOpen;
773
- const setOpen = (next) => {
774
- if (!isControlled) setInternalOpen(next);
775
- onOpenChange?.(next);
776
- };
777
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
778
- import_popover.Popover.Root,
779
- {
780
- open,
781
- onOpenChange: (details) => setOpen(details.open),
782
- positioning: {
783
- placement: align === "end" ? "bottom-end" : "bottom-start"
784
- },
785
- children: [
786
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
787
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_portal2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
788
- import_popover.Popover.Content,
789
- {
790
- "data-theme": theme,
791
- className: cn2(
792
- "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
793
- panelClassName ?? DEFAULT_PANEL,
794
- className
795
- ),
796
- children: typeof children === "function" ? children(() => setOpen(false)) : children
797
- }
798
- ) }) })
799
- ]
800
- }
761
+ const colorClasses = intent ? intentClasses2[intent] : themeClasses;
762
+ return cn(
763
+ "polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border",
764
+ disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
765
+ colorClasses,
766
+ sizes[size || "md"],
767
+ className
801
768
  );
802
769
  };
803
-
804
- // src/primitives/icons/index.tsx
770
+ function Button({
771
+ as,
772
+ children,
773
+ theme,
774
+ intent,
775
+ size,
776
+ className,
777
+ disabled,
778
+ ...buttonProps
779
+ }) {
780
+ const Component = as || "button";
781
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
782
+ Component,
783
+ {
784
+ "data-theme": intent ? void 0 : theme,
785
+ "data-intent": intent,
786
+ className: buttonClasses({
787
+ theme,
788
+ intent,
789
+ size,
790
+ className,
791
+ disabled
792
+ }),
793
+ disabled,
794
+ ...buttonProps,
795
+ children
796
+ }
797
+ );
798
+ }
799
+
800
+ // src/primitives/icons/index.tsx
805
801
  var import_jsx_runtime11 = require("react/jsx-runtime");
806
802
  var strokeProps = {
807
803
  fill: "none",
@@ -895,6 +891,13 @@ function ImageIcon(props) {
895
891
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m21 15-5-5L5 21" })
896
892
  ] });
897
893
  }
894
+ function AudioIcon(props) {
895
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M9 18V5l12-2v13" }),
897
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
898
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "18", cy: "16", r: "3" })
899
+ ] });
900
+ }
898
901
  function LockIcon(props) {
899
902
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
900
903
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
@@ -917,6 +920,9 @@ function McpIcon(props) {
917
920
  function MenuIcon(props) {
918
921
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 7h16M4 12h16M4 17h16" }) });
919
922
  }
923
+ function PlusIcon(props) {
924
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 5v14M5 12h14" }) });
925
+ }
920
926
  function TerminalIcon(props) {
921
927
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
922
928
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("polyline", { points: "4 8 8 12 4 16" }),
@@ -943,12 +949,12 @@ function XIcon(props) {
943
949
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) });
944
950
  }
945
951
 
946
- // src/primitives/ExternalLinkButton.tsx
952
+ // src/compositions/ExternalLinkButton.tsx
947
953
  var import_jsx_runtime12 = require("react/jsx-runtime");
948
954
  var ExternalLinkButton = ({
949
955
  theme,
950
956
  href,
951
- size = "medium",
957
+ size = "md",
952
958
  className,
953
959
  children
954
960
  }) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
@@ -960,7 +966,7 @@ var ExternalLinkButton = ({
960
966
  rel: "noopener noreferrer",
961
967
  theme,
962
968
  size,
963
- className: cn2("polli:gap-2", className),
969
+ className: cn("polli:gap-2", className),
964
970
  children: [
965
971
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children }),
966
972
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
@@ -974,13 +980,48 @@ var ExternalLinkButton = ({
974
980
  }
975
981
  );
976
982
 
977
- // src/primitives/Field.tsx
978
- var import_field = require("@ark-ui/react/field");
983
+ // src/compositions/FileUpload.tsx
984
+ var import_react5 = require("react");
985
+
986
+ // src/lib/partition-files.ts
987
+ function matchesAccept(file, accept) {
988
+ if (!accept) return true;
989
+ const tokens = accept.split(",").map((t) => t.trim()).filter(Boolean);
990
+ if (tokens.length === 0) return true;
991
+ return tokens.some((token) => {
992
+ if (token.startsWith(".")) {
993
+ return file.name.toLowerCase().endsWith(token.toLowerCase());
994
+ }
995
+ if (token.endsWith("/*")) {
996
+ const prefix = token.slice(0, token.length - 1);
997
+ return file.type.startsWith(prefix);
998
+ }
999
+ return file.type === token;
1000
+ });
1001
+ }
1002
+ function partitionFiles(incoming, current, { maxFiles, maxSizeBytes, accept }) {
1003
+ const accepted = [];
1004
+ const rejected = [];
1005
+ let slots = Math.max(0, maxFiles - current.length);
1006
+ for (const file of incoming) {
1007
+ if (!matchesAccept(file, accept)) {
1008
+ rejected.push({ file, reason: "type" });
1009
+ } else if (file.size > maxSizeBytes) {
1010
+ rejected.push({ file, reason: "size" });
1011
+ } else if (slots <= 0) {
1012
+ rejected.push({ file, reason: "count" });
1013
+ } else {
1014
+ accepted.push(file);
1015
+ slots -= 1;
1016
+ }
1017
+ }
1018
+ return { accepted, rejected };
1019
+ }
979
1020
 
980
1021
  // src/primitives/IconButton.tsx
981
1022
  var import_jsx_runtime13 = require("react/jsx-runtime");
982
- var intentClasses4 = {
983
- danger: "polli:bg-intent-danger-bg-light polli:hover:bg-[oklch(0.88_0.075_25)] polli:text-intent-danger-text"
1023
+ var intentClasses3 = {
1024
+ danger: "polli:bg-intent-danger-bg-light polli:hover:bg-intent-danger-bg-hover polli:text-intent-danger-text"
984
1025
  };
985
1026
  var defaultClasses = "polli:bg-theme-bg-active polli:hover:bg-theme-bg-hover polli:text-theme-text-soft polli:hover:text-theme-text-strong";
986
1027
  var IconButton = ({
@@ -996,137 +1037,535 @@ var IconButton = ({
996
1037
  onClick,
997
1038
  title,
998
1039
  "aria-label": title,
999
- className: cn2(
1000
- "polli:inline-flex polli:h-6 polli:w-6 polli:cursor-pointer polli:items-center polli:justify-center polli:rounded polli:transition-colors",
1001
- intent ? intentClasses4[intent] : defaultClasses,
1040
+ "data-intent": intent,
1041
+ className: cn(
1042
+ "polli-control polli:inline-flex polli:h-6 polli:w-6 polli:cursor-pointer polli:items-center polli:justify-center polli:rounded polli:transition-colors",
1043
+ intent ? intentClasses3[intent] : defaultClasses,
1002
1044
  className
1003
1045
  ),
1004
1046
  children
1005
1047
  }
1006
1048
  );
1007
1049
 
1008
- // src/primitives/InfoTip.tsx
1050
+ // src/compositions/FileUpload.tsx
1009
1051
  var import_jsx_runtime14 = require("react/jsx-runtime");
1052
+ var PREVIEWABLE_IMAGE_TYPES = /* @__PURE__ */ new Set([
1053
+ "image/gif",
1054
+ "image/jpeg",
1055
+ "image/png",
1056
+ "image/webp"
1057
+ ]);
1058
+ var PREVIEW_SIZE = 64;
1059
+ var LARGE_PREVIEW_SIZE = 112;
1060
+ var previewSizeClasses = {
1061
+ sm: "polli:h-16 polli:w-16",
1062
+ lg: "polli:h-28 polli:w-28"
1063
+ };
1064
+ function isPreviewableImage(file) {
1065
+ return PREVIEWABLE_IMAGE_TYPES.has(file.type);
1066
+ }
1067
+ function formatFileSize(bytes) {
1068
+ if (bytes < 1024) return `${bytes} B`;
1069
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
1070
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1071
+ }
1072
+ function PreviewPlaceholder({
1073
+ icon,
1074
+ size
1075
+ }) {
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1077
+ "div",
1078
+ {
1079
+ className: cn(
1080
+ "polli:flex polli:items-center polli:justify-center polli:rounded-lg polli:bg-theme-bg-active polli:text-theme-text-soft",
1081
+ previewSizeClasses[size]
1082
+ ),
1083
+ children: icon
1084
+ }
1085
+ );
1086
+ }
1087
+ function FilePreview({
1088
+ file,
1089
+ placeholderIcon,
1090
+ size = "sm"
1091
+ }) {
1092
+ const canvasRef = (0, import_react5.useRef)(null);
1093
+ const [canPreview, setCanPreview] = (0, import_react5.useState)(
1094
+ () => isPreviewableImage(file)
1095
+ );
1096
+ const previewSize = size === "lg" ? LARGE_PREVIEW_SIZE : PREVIEW_SIZE;
1097
+ (0, import_react5.useEffect)(() => {
1098
+ if (!isPreviewableImage(file)) {
1099
+ setCanPreview(false);
1100
+ return;
1101
+ }
1102
+ let cancelled = false;
1103
+ setCanPreview(true);
1104
+ async function drawPreview() {
1105
+ try {
1106
+ const bitmap = await createImageBitmap(file);
1107
+ if (cancelled) {
1108
+ bitmap.close();
1109
+ return;
1110
+ }
1111
+ const canvas = canvasRef.current;
1112
+ const context = canvas?.getContext("2d");
1113
+ if (!canvas || !context) {
1114
+ bitmap.close();
1115
+ setCanPreview(false);
1116
+ return;
1117
+ }
1118
+ canvas.width = previewSize;
1119
+ canvas.height = previewSize;
1120
+ const scale = Math.max(
1121
+ previewSize / bitmap.width,
1122
+ previewSize / bitmap.height
1123
+ );
1124
+ const width = bitmap.width * scale;
1125
+ const height = bitmap.height * scale;
1126
+ const x = (previewSize - width) / 2;
1127
+ const y = (previewSize - height) / 2;
1128
+ context.clearRect(0, 0, previewSize, previewSize);
1129
+ context.drawImage(bitmap, x, y, width, height);
1130
+ bitmap.close();
1131
+ } catch {
1132
+ if (!cancelled) setCanPreview(false);
1133
+ }
1134
+ }
1135
+ void drawPreview();
1136
+ return () => {
1137
+ cancelled = true;
1138
+ };
1139
+ }, [file, previewSize]);
1140
+ if (!canPreview) {
1141
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewPlaceholder, { icon: placeholderIcon, size });
1142
+ }
1143
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1144
+ "canvas",
1145
+ {
1146
+ ref: canvasRef,
1147
+ role: "img",
1148
+ "aria-label": file.name,
1149
+ className: cn("polli:rounded-lg", previewSizeClasses[size]),
1150
+ width: previewSize,
1151
+ height: previewSize
1152
+ }
1153
+ );
1154
+ }
1155
+ function FileUpload({
1156
+ value,
1157
+ onChange,
1158
+ onReject,
1159
+ maxFiles = 4,
1160
+ maxSizeBytes = 10 * 1024 * 1024,
1161
+ accept = "image/*",
1162
+ icon = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ImageIcon, { className: "polli:h-6 polli:w-6" }),
1163
+ label = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1164
+ "Drag images here or ",
1165
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "polli:underline", children: "browse" })
1166
+ ] }),
1167
+ previewIcon = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ImageIcon, { className: "polli:h-5 polli:w-5" }),
1168
+ disabled = false,
1169
+ theme,
1170
+ className
1171
+ }) {
1172
+ (0, import_react5.useEffect)(() => {
1173
+ const prevent = (event) => event.preventDefault();
1174
+ document.addEventListener("dragover", prevent);
1175
+ document.addEventListener("drop", prevent);
1176
+ return () => {
1177
+ document.removeEventListener("dragover", prevent);
1178
+ document.removeEventListener("drop", prevent);
1179
+ };
1180
+ }, []);
1181
+ function addFiles(incoming) {
1182
+ if (disabled || incoming.length === 0) return;
1183
+ const { accepted, rejected } = partitionFiles(incoming, value, {
1184
+ maxFiles,
1185
+ maxSizeBytes,
1186
+ accept
1187
+ });
1188
+ if (accepted.length > 0) onChange([...value, ...accepted]);
1189
+ if (rejected.length > 0) onReject?.(rejected);
1190
+ }
1191
+ const hasFiles = value.length > 0;
1192
+ const canAdd = !disabled && value.length < maxFiles;
1193
+ const isSingleFile = maxFiles === 1;
1194
+ const previewSize = isSingleFile ? "lg" : "sm";
1195
+ const inputId = (0, import_react5.useId)();
1196
+ const addInputId = `${inputId}-add`;
1197
+ function handleInputChange(event) {
1198
+ addFiles(Array.from(event.target.files ?? []));
1199
+ event.target.value = "";
1200
+ }
1201
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1202
+ "div",
1203
+ {
1204
+ "data-theme": theme,
1205
+ className: cn("polli:flex polli:flex-col polli:gap-2", className),
1206
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1207
+ "fieldset",
1208
+ {
1209
+ disabled,
1210
+ className: cn(
1211
+ "polli:m-0",
1212
+ "polli:rounded-xl polli:border polli:border-dashed polli:border-theme-border polli:bg-theme-bg-pale",
1213
+ "polli:px-4 polli:py-4 polli:text-center polli:text-sm",
1214
+ "polli:text-theme-text-soft polli:transition-colors",
1215
+ disabled ? "polli:opacity-50" : "polli:hover:bg-theme-bg-hover"
1216
+ ),
1217
+ onDragOver: (e) => e.preventDefault(),
1218
+ onDrop: (e) => {
1219
+ e.preventDefault();
1220
+ if (disabled) return;
1221
+ addFiles(Array.from(e.dataTransfer.files));
1222
+ },
1223
+ children: !hasFiles ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1224
+ "label",
1225
+ {
1226
+ htmlFor: inputId,
1227
+ className: cn(
1228
+ "polli-control polli:flex polli:min-h-32 polli:flex-col polli:items-center polli:justify-center polli:gap-2 polli:rounded-lg",
1229
+ canAdd ? "polli:cursor-pointer" : "polli:cursor-not-allowed"
1230
+ ),
1231
+ children: [
1232
+ icon,
1233
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: label }),
1234
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1235
+ "input",
1236
+ {
1237
+ id: inputId,
1238
+ type: "file",
1239
+ accept,
1240
+ multiple: maxFiles > 1,
1241
+ disabled: disabled || !canAdd,
1242
+ className: "polli:sr-only",
1243
+ onChange: handleInputChange
1244
+ }
1245
+ )
1246
+ ]
1247
+ }
1248
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "polli:flex polli:flex-col polli:gap-3", children: [
1249
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1250
+ "ul",
1251
+ {
1252
+ className: cn(
1253
+ "polli:m-0 polli:grid polli:grid-cols-[repeat(auto-fill,minmax(5rem,1fr))] polli:gap-3 polli:p-0",
1254
+ isSingleFile && "polli:flex polli:justify-center"
1255
+ ),
1256
+ children: [
1257
+ value.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1258
+ "li",
1259
+ {
1260
+ className: cn(
1261
+ "polli:relative polli:flex polli:min-w-0 polli:list-none polli:flex-col polli:items-center polli:gap-1",
1262
+ isSingleFile && "polli:max-w-full"
1263
+ ),
1264
+ children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1266
+ FilePreview,
1267
+ {
1268
+ file,
1269
+ placeholderIcon: previewIcon,
1270
+ size: previewSize
1271
+ }
1272
+ ),
1273
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1274
+ "span",
1275
+ {
1276
+ className: cn(
1277
+ "polli:max-w-full polli:truncate polli:text-xs polli:font-medium polli:text-theme-text-base",
1278
+ isSingleFile ? "polli:w-36" : "polli:w-16"
1279
+ ),
1280
+ children: file.name
1281
+ }
1282
+ ),
1283
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "polli:text-micro polli:text-theme-text-muted", children: formatFileSize(file.size) }),
1284
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "polli:absolute polli:-top-2 polli:right-1", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1285
+ IconButton,
1286
+ {
1287
+ intent: "danger",
1288
+ title: `Remove ${file.name}`,
1289
+ onClick: () => onChange(
1290
+ value.filter(
1291
+ (_, i) => i !== index
1292
+ )
1293
+ ),
1294
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(XIcon, { className: "polli:h-3 polli:w-3" })
1295
+ }
1296
+ ) })
1297
+ ]
1298
+ },
1299
+ `${file.name}-${index}`
1300
+ )),
1301
+ !isSingleFile && canAdd && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("li", { className: "polli:flex polli:list-none", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1302
+ "label",
1303
+ {
1304
+ htmlFor: addInputId,
1305
+ className: "polli-control polli:flex polli:min-h-20 polli:w-full polli:cursor-pointer polli:flex-col polli:items-center polli:justify-center polli:gap-1 polli:rounded-lg polli:bg-theme-bg-active polli:px-3 polli:py-2 polli:text-theme-text-soft polli:transition-colors polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-strong",
1306
+ children: [
1307
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PlusIcon, { className: "polli:h-5 polli:w-5" }),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "polli:text-xs polli:font-medium", children: "Add" }),
1309
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1310
+ "input",
1311
+ {
1312
+ id: addInputId,
1313
+ type: "file",
1314
+ accept,
1315
+ multiple: true,
1316
+ disabled: disabled || !canAdd,
1317
+ className: "polli:sr-only",
1318
+ onChange: handleInputChange
1319
+ }
1320
+ )
1321
+ ]
1322
+ }
1323
+ ) })
1324
+ ]
1325
+ }
1326
+ ),
1327
+ maxFiles > 1 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "polli:text-xs polli:text-theme-text-muted", children: [
1328
+ value.length,
1329
+ " / ",
1330
+ maxFiles,
1331
+ " files"
1332
+ ] })
1333
+ ] })
1334
+ }
1335
+ )
1336
+ }
1337
+ );
1338
+ }
1339
+
1340
+ // src/compositions/InfoTip.tsx
1341
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1010
1342
  var InfoTip = ({
1011
1343
  text,
1012
1344
  content,
1013
1345
  label = "More info"
1014
- }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Tooltip, { content: content ?? text, ariaLabel: label, className: "polli:ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "polli:inline-flex polli:h-3.5 polli:w-3.5 polli:items-center polli:justify-center polli:rounded-full polli:border polli:border-theme-border polli:bg-theme-bg-active polli:font-bold polli:text-micro polli:text-theme-text-strong polli:transition-colors", children: "i" }) });
1346
+ }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tooltip, { content: content ?? text, ariaLabel: label, className: "polli:ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "polli:inline-flex polli:h-3.5 polli:w-3.5 polli:items-center polli:justify-center polli:rounded-full polli:border polli:border-theme-border polli:bg-theme-bg-active polli:font-bold polli:text-micro polli:text-theme-text-strong polli:transition-colors", children: "i" }) });
1015
1347
 
1016
- // src/primitives/Input.tsx
1017
- var import_react5 = require("react");
1018
- var import_jsx_runtime15 = require("react/jsx-runtime");
1019
- var Input = (0, import_react5.forwardRef)(
1020
- ({ className, error, hideNumberSteppers, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1021
- "input",
1348
+ // src/primitives/Surface.tsx
1349
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1350
+ var variantClasses = {
1351
+ panel: "polli:rounded-2xl polli:border polli:border-theme-border polli:bg-theme-bg-subtle polli:p-6",
1352
+ card: "polli:rounded-xl polli:bg-surface-white polli:p-4",
1353
+ "card-themed": "polli:rounded-xl polli:bg-theme-bg-pale polli:p-4"
1354
+ };
1355
+ var Surface = ({
1356
+ theme,
1357
+ variant = "card",
1358
+ className,
1359
+ children,
1360
+ ...rest
1361
+ }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1362
+ "div",
1363
+ {
1364
+ ...rest,
1365
+ "data-theme": theme,
1366
+ className: cn("polli:min-w-0", variantClasses[variant], className),
1367
+ children
1368
+ }
1369
+ );
1370
+
1371
+ // src/compositions/LinkCard.tsx
1372
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1373
+ function isExternalHref(href) {
1374
+ return typeof href === "string" && /^https?:\/\//.test(href);
1375
+ }
1376
+ function LinkCard({
1377
+ as,
1378
+ theme,
1379
+ external,
1380
+ showIcon = true,
1381
+ className,
1382
+ surfaceClassName,
1383
+ children,
1384
+ ...linkProps
1385
+ }) {
1386
+ const Component = as || "a";
1387
+ const isExternal = external ?? isExternalHref(linkProps.href);
1388
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1389
+ Component,
1022
1390
  {
1023
- ref,
1024
- className: cn2(
1025
- "polli:px-3 polli:py-2 polli:border polli:rounded-lg",
1026
- "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
1027
- error ? "polli:border-red-400" : "polli:border-gray-300",
1028
- hideNumberSteppers && "polli-input-number-clean",
1391
+ "data-theme": theme,
1392
+ target: isExternal ? "_blank" : void 0,
1393
+ rel: isExternal ? "noopener noreferrer" : void 0,
1394
+ className: cn(
1395
+ "polli:group polli:block polli:h-full polli:rounded-xl polli:outline-none",
1029
1396
  className
1030
1397
  ),
1398
+ ...linkProps,
1399
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1400
+ Surface,
1401
+ {
1402
+ theme,
1403
+ variant: "card",
1404
+ className: cn(
1405
+ "polli:relative polli:flex polli:h-full polli:flex-col polli:gap-2 polli:bg-surface-opaque/80 polli:p-5",
1406
+ showIcon && isExternal && "polli:pr-10",
1407
+ "polli:transition polli:group-hover:-translate-y-0.5 polli:group-hover:bg-surface-opaque/95",
1408
+ "polli:group-focus-visible:ring-2 polli:group-focus-visible:ring-theme-border",
1409
+ surfaceClassName
1410
+ ),
1411
+ children: [
1412
+ showIcon && isExternal && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1413
+ ExternalLinkIcon,
1414
+ {
1415
+ "aria-hidden": "true",
1416
+ className: "polli:absolute polli:top-4 polli:right-4 polli:h-3.5 polli:w-3.5 polli:text-theme-text-soft"
1417
+ }
1418
+ ),
1419
+ children
1420
+ ]
1421
+ }
1422
+ )
1423
+ }
1424
+ );
1425
+ }
1426
+
1427
+ // src/compositions/Markdown.tsx
1428
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
1429
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
1430
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1431
+ var components = {
1432
+ ul: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1433
+ "ul",
1434
+ {
1435
+ className: "polli:flex polli:min-w-0 polli:list-disc polli:flex-col polli:gap-1 polli:pl-5 polli:marker:text-theme-text-muted",
1436
+ ...props
1437
+ }
1438
+ ),
1439
+ ol: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1440
+ "ol",
1441
+ {
1442
+ className: "polli:flex polli:min-w-0 polli:list-decimal polli:flex-col polli:gap-1 polli:pl-5 polli:marker:text-theme-text-muted",
1443
+ ...props
1444
+ }
1445
+ ),
1446
+ p: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "polli:mb-2 polli:last:mb-0", ...props }),
1447
+ strong: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1448
+ "strong",
1449
+ {
1450
+ className: "polli:font-semibold polli:text-theme-text-strong",
1451
+ ...props
1452
+ }
1453
+ ),
1454
+ code: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1455
+ "code",
1456
+ {
1457
+ className: "polli:break-words polli:rounded polli:bg-theme-bg-subtle polli:px-1 polli:py-0.5 polli:font-mono polli:text-xs",
1458
+ ...props
1459
+ }
1460
+ ),
1461
+ a: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1462
+ "a",
1463
+ {
1464
+ target: "_blank",
1465
+ rel: "noopener noreferrer",
1466
+ className: "polli-control polli:rounded-sm polli:font-semibold polli:text-theme-text-strong polli:underline polli:underline-offset-2",
1031
1467
  ...props
1032
1468
  }
1033
1469
  )
1034
- );
1035
-
1036
- // src/primitives/ScrollArea.tsx
1037
- var import_react6 = require("react");
1038
- var import_jsx_runtime16 = require("react/jsx-runtime");
1039
- var axisClasses = {
1040
- y: "polli:overflow-y-auto polli:overflow-x-hidden",
1041
- x: "polli:overflow-x-auto polli:overflow-y-hidden"
1042
1470
  };
1043
- function assignRef(ref, value) {
1044
- if (typeof ref === "function") ref(value);
1045
- else if (ref) ref.current = value;
1471
+ function Markdown({ children, className }) {
1472
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1473
+ "div",
1474
+ {
1475
+ className: cn(
1476
+ "polli:min-w-0 polli:font-body polli:leading-relaxed",
1477
+ className
1478
+ ),
1479
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], components, children })
1480
+ }
1481
+ );
1046
1482
  }
1047
- var ScrollArea = (0, import_react6.forwardRef)(
1048
- ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
1049
- const innerRef = (0, import_react6.useRef)(null);
1050
- const setRef = (0, import_react6.useCallback)(
1051
- (node) => {
1052
- innerRef.current = node;
1053
- assignRef(externalRef, node);
1054
- },
1055
- [externalRef]
1056
- );
1057
- (0, import_react6.useEffect)(() => {
1058
- const element = innerRef.current;
1059
- if (!element) return;
1060
- let hideTimer = null;
1061
- const clearHideTimer = () => {
1062
- if (hideTimer !== null) {
1063
- window.clearTimeout(hideTimer);
1064
- hideTimer = null;
1065
- }
1066
- };
1067
- const show = () => {
1068
- element.dataset.scrollbarActive = "true";
1069
- clearHideTimer();
1070
- };
1071
- const hide = () => {
1072
- element.dataset.scrollbarActive = "false";
1073
- clearHideTimer();
1074
- };
1075
- const scheduleHide = () => {
1076
- clearHideTimer();
1077
- hideTimer = window.setTimeout(hide, 2e3);
1078
- };
1079
- const handleInteraction = () => {
1080
- show();
1081
- scheduleHide();
1082
- };
1083
- hide();
1084
- element.addEventListener("scroll", handleInteraction, {
1085
- passive: true
1086
- });
1087
- element.addEventListener("wheel", handleInteraction, {
1088
- passive: true
1089
- });
1090
- element.addEventListener("touchstart", handleInteraction, {
1091
- passive: true
1092
- });
1093
- element.addEventListener("pointerdown", handleInteraction);
1094
- element.addEventListener("keydown", handleInteraction);
1095
- element.addEventListener("focusin", handleInteraction);
1096
- element.addEventListener("focusout", scheduleHide);
1097
- return () => {
1098
- clearHideTimer();
1099
- element.removeEventListener("scroll", handleInteraction);
1100
- element.removeEventListener("wheel", handleInteraction);
1101
- element.removeEventListener("touchstart", handleInteraction);
1102
- element.removeEventListener("pointerdown", handleInteraction);
1103
- element.removeEventListener("keydown", handleInteraction);
1104
- element.removeEventListener("focusin", handleInteraction);
1105
- element.removeEventListener("focusout", scheduleHide);
1106
- };
1107
- }, []);
1108
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1109
- "div",
1110
- {
1111
- ...rest,
1112
- ref: setRef,
1113
- "data-theme": theme,
1114
- className: cn2(
1115
- "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
1116
- axisClasses[axis],
1117
- className
1118
- ),
1119
- children
1120
- }
1121
- );
1483
+
1484
+ // src/compositions/MediaPlaceholder.tsx
1485
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1486
+ var MediaPlaceholder = ({
1487
+ theme,
1488
+ icon,
1489
+ label,
1490
+ detail,
1491
+ action,
1492
+ children,
1493
+ className,
1494
+ ...rest
1495
+ }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1496
+ "div",
1497
+ {
1498
+ ...rest,
1499
+ "data-theme": theme,
1500
+ className: cn(
1501
+ "polli:flex polli:aspect-video polli:min-h-40 polli:flex-col polli:items-center polli:justify-center polli:gap-3 polli:rounded-lg polli:border polli:border-dashed polli:border-theme-border polli:bg-theme-bg-pale polli:p-6 polli:text-center",
1502
+ className
1503
+ ),
1504
+ children: [
1505
+ icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:flex polli:h-10 polli:w-10 polli:items-center polli:justify-center polli:rounded-full polli:bg-theme-bg-active polli:text-theme-text-base", children: icon }),
1506
+ (label || detail) && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "polli:max-w-sm", children: [
1507
+ label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { as: "p", size: "sm", tone: "strong", weight: "semibold", children: label }),
1508
+ detail && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { as: "p", size: "sm", tone: "soft", className: "polli:mt-1", children: detail })
1509
+ ] }),
1510
+ children,
1511
+ action
1512
+ ]
1122
1513
  }
1123
1514
  );
1124
- ScrollArea.displayName = "ScrollArea";
1125
1515
 
1126
- // src/primitives/MultiSelect.tsx
1127
- var import_jsx_runtime17 = require("react/jsx-runtime");
1128
- var TRIGGER_BASE = "polli:inline-flex polli:min-h-8 polli:min-w-[140px] polli:items-center polli:gap-2 polli:rounded-full polli:border polli:px-3 polli:py-1.5 polli:text-xs polli:font-medium polli:transition-all polli:duration-200";
1129
- var ROW_BASE = "polli:flex polli:w-full polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:text-xs polli:transition-colors";
1516
+ // src/primitives/Dropdown.tsx
1517
+ var import_popover = require("@ark-ui/react/popover");
1518
+ var import_portal = require("@ark-ui/react/portal");
1519
+ var import_react6 = require("react");
1520
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1521
+ var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
1522
+ var Dropdown = ({
1523
+ theme,
1524
+ trigger,
1525
+ children,
1526
+ align = "start",
1527
+ open: openProp,
1528
+ onOpenChange,
1529
+ className
1530
+ }) => {
1531
+ const [internalOpen, setInternalOpen] = (0, import_react6.useState)(false);
1532
+ const isControlled = openProp !== void 0;
1533
+ const open = isControlled ? openProp : internalOpen;
1534
+ const setOpen = (next) => {
1535
+ if (!isControlled) setInternalOpen(next);
1536
+ onOpenChange?.(next);
1537
+ };
1538
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1539
+ import_popover.Popover.Root,
1540
+ {
1541
+ open,
1542
+ onOpenChange: (details) => setOpen(details.open),
1543
+ positioning: {
1544
+ placement: align === "end" ? "bottom-end" : "bottom-start"
1545
+ },
1546
+ children: [
1547
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
1548
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1549
+ import_popover.Popover.Content,
1550
+ {
1551
+ "data-theme": theme,
1552
+ className: cn(
1553
+ "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
1554
+ DEFAULT_PANEL,
1555
+ className
1556
+ ),
1557
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
1558
+ }
1559
+ ) }) })
1560
+ ]
1561
+ }
1562
+ );
1563
+ };
1564
+
1565
+ // src/compositions/MultiSelect.tsx
1566
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1567
+ var TRIGGER_BASE = "polli-control polli:inline-flex polli:min-h-8 polli:min-w-[140px] polli:items-center polli:gap-2 polli:rounded-full polli:border polli:px-3 polli:py-1.5 polli:text-xs polli:font-medium polli:transition-all polli:duration-200";
1568
+ var ROW_BASE = "polli-control polli:flex polli:w-full polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:text-xs polli:transition-colors";
1130
1569
  var CHECK_BASE = "polli:flex polli:h-4 polli:w-4 polli:flex-shrink-0 polli:items-center polli:justify-center polli:rounded polli:border polli:border-theme-border polli:text-xs";
1131
1570
  var MultiSelect = ({
1132
1571
  options,
@@ -1149,27 +1588,27 @@ var MultiSelect = ({
1149
1588
  };
1150
1589
  const selectAll = () => onChange([]);
1151
1590
  const displayText = disabled ? disabledText : isAllSelected ? "All" : `${selected.length} selected`;
1152
- const labelNode = label ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "polli:text-xs polli:font-medium polli:text-theme-text-soft", children: label }) : null;
1591
+ const labelNode = label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "polli:text-xs polli:font-medium polli:text-theme-text-soft", children: label }) : null;
1153
1592
  if (disabled) {
1154
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1593
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1155
1594
  "div",
1156
1595
  {
1157
1596
  "data-theme": theme,
1158
1597
  className: "polli:group polli:relative polli:flex polli:items-center polli:gap-2",
1159
1598
  children: [
1160
1599
  labelNode,
1161
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1600
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1162
1601
  "button",
1163
1602
  {
1164
1603
  type: "button",
1165
1604
  disabled: true,
1166
- className: cn2(
1605
+ className: cn(
1167
1606
  TRIGGER_BASE,
1168
1607
  "polli:cursor-not-allowed polli:border-theme-border polli:bg-theme-bg-subtle polli:opacity-60"
1169
1608
  ),
1170
1609
  children: [
1171
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "polli:flex-1 polli:truncate polli:text-left polli:text-theme-text-soft/60", children: displayText }),
1172
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1610
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "polli:flex-1 polli:truncate polli:text-left polli:text-theme-text-soft/60", children: displayText }),
1611
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1173
1612
  ChevronIcon,
1174
1613
  {
1175
1614
  expanded: false,
@@ -1179,48 +1618,48 @@ var MultiSelect = ({
1179
1618
  ]
1180
1619
  }
1181
1620
  ),
1182
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "polli:pointer-events-none polli:absolute polli:-top-8 polli:left-1/2 polli:z-[100] polli:-translate-x-1/2 polli:whitespace-nowrap polli:rounded-md polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:px-2 polli:py-1 polli:text-xs polli:text-theme-text-strong polli:opacity-0 polli:shadow-sm polli:transition-opacity polli:group-hover:opacity-100", children: "No items available" })
1621
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "polli:pointer-events-none polli:absolute polli:-top-8 polli:left-1/2 polli:z-[100] polli:-translate-x-1/2 polli:whitespace-nowrap polli:rounded-md polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:px-2 polli:py-1 polli:text-xs polli:text-theme-text-strong polli:opacity-0 polli:shadow-sm polli:transition-opacity polli:group-hover:opacity-100", children: "No items available" })
1183
1622
  ]
1184
1623
  }
1185
1624
  );
1186
1625
  }
1187
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1626
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1188
1627
  "div",
1189
1628
  {
1190
1629
  "data-theme": theme,
1191
1630
  className: "polli:flex polli:items-center polli:gap-2",
1192
1631
  children: [
1193
1632
  labelNode,
1194
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1633
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1195
1634
  Dropdown,
1196
1635
  {
1197
1636
  theme,
1198
1637
  align,
1199
1638
  className: "polli:min-w-[320px]",
1200
- trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1639
+ trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1201
1640
  "button",
1202
1641
  {
1203
1642
  type: "button",
1204
- className: cn2(
1643
+ className: cn(
1205
1644
  TRIGGER_BASE,
1206
1645
  open ? "polli:border-theme-border polli:bg-theme-bg-active" : "polli:border-theme-border polli:bg-theme-bg-subtle polli:hover:bg-theme-bg-pale"
1207
1646
  ),
1208
1647
  children: [
1209
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1648
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1210
1649
  "span",
1211
1650
  {
1212
- className: cn2(
1651
+ className: cn(
1213
1652
  "polli:flex-1 polli:truncate polli:text-left",
1214
1653
  open ? "polli:text-theme-text-strong" : "polli:text-theme-text-base"
1215
1654
  ),
1216
1655
  children: displayText
1217
1656
  }
1218
1657
  ),
1219
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1658
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1220
1659
  ChevronIcon,
1221
1660
  {
1222
1661
  expanded: open,
1223
- className: cn2(
1662
+ className: cn(
1224
1663
  "polli:h-3 polli:w-3 polli:transition-transform",
1225
1664
  open ? "polli:text-theme-text-strong" : "polli:text-theme-text-soft"
1226
1665
  )
@@ -1229,21 +1668,21 @@ var MultiSelect = ({
1229
1668
  ]
1230
1669
  }
1231
1670
  ),
1232
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(ScrollArea, { theme, className: "polli:max-h-64", children: [
1233
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1671
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(ScrollArea, { theme, className: "polli:max-h-64", children: [
1672
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1234
1673
  "button",
1235
1674
  {
1236
1675
  type: "button",
1237
1676
  onClick: selectAll,
1238
- className: cn2(
1677
+ className: cn(
1239
1678
  ROW_BASE,
1240
1679
  isAllSelected ? "polli:bg-theme-bg-active polli:font-medium polli:text-theme-text-strong" : "polli:text-theme-text-base polli:hover:bg-theme-bg-subtle"
1241
1680
  ),
1242
1681
  children: [
1243
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1682
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1244
1683
  "span",
1245
1684
  {
1246
- className: cn2(
1685
+ className: cn(
1247
1686
  CHECK_BASE,
1248
1687
  isAllSelected && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1249
1688
  ),
@@ -1256,27 +1695,27 @@ var MultiSelect = ({
1256
1695
  ),
1257
1696
  options.map((opt) => {
1258
1697
  const isChecked = selected.includes(opt.value);
1259
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1698
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1260
1699
  "button",
1261
1700
  {
1262
1701
  type: "button",
1263
1702
  onClick: () => toggleItem(opt.value),
1264
- className: cn2(
1703
+ className: cn(
1265
1704
  ROW_BASE,
1266
1705
  isChecked ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-theme-text-base polli:hover:bg-theme-bg-subtle"
1267
1706
  ),
1268
1707
  children: [
1269
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1708
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1270
1709
  "span",
1271
1710
  {
1272
- className: cn2(
1711
+ className: cn(
1273
1712
  CHECK_BASE,
1274
1713
  isChecked && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1275
1714
  ),
1276
1715
  children: isChecked && "\u2713"
1277
1716
  }
1278
1717
  ),
1279
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "polli:whitespace-nowrap", children: opt.label })
1718
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "polli:whitespace-nowrap", children: opt.label })
1280
1719
  ]
1281
1720
  },
1282
1721
  opt.value
@@ -1290,26 +1729,179 @@ var MultiSelect = ({
1290
1729
  );
1291
1730
  };
1292
1731
 
1293
- // src/primitives/PeriodPicker.tsx
1732
+ // src/compositions/NavItem.tsx
1733
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1734
+ var base = "polli-control polli:flex polli:items-center polli:gap-2 polli:rounded-full polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:whitespace-nowrap polli:transition-colors";
1735
+ var activeClasses = "polli:bg-theme-bg-active polli:text-theme-text-strong";
1736
+ var inactiveClasses = "polli:text-ink-800 polli:hover:bg-surface-opaque/60 polli:hover:text-ink-950";
1737
+ var dotClasses = "polli:h-2.5 polli:w-2.5 polli:shrink-0 polli:rounded-full polli:bg-theme-bg-hover polli:ring-1 polli:ring-inset polli:ring-ink-950/10";
1738
+ function NavItem({
1739
+ as,
1740
+ theme,
1741
+ active = false,
1742
+ className,
1743
+ children,
1744
+ ...rest
1745
+ }) {
1746
+ const Component = as || "button";
1747
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1748
+ Component,
1749
+ {
1750
+ "data-theme": theme,
1751
+ "aria-current": active ? "page" : void 0,
1752
+ className: cn(
1753
+ base,
1754
+ active ? activeClasses : inactiveClasses,
1755
+ className
1756
+ ),
1757
+ ...rest,
1758
+ children: [
1759
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", className: dotClasses }),
1760
+ children
1761
+ ]
1762
+ }
1763
+ );
1764
+ }
1765
+
1766
+ // src/compositions/PeriodPicker.tsx
1294
1767
  var import_react7 = require("react");
1295
1768
 
1769
+ // src/lib/period.ts
1770
+ var MS_PER_DAY = 864e5;
1771
+ function startOfUtcDay(date = /* @__PURE__ */ new Date()) {
1772
+ return new Date(
1773
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
1774
+ );
1775
+ }
1776
+ function addUtcDays(date, days) {
1777
+ const next = new Date(date);
1778
+ next.setUTCDate(next.getUTCDate() + days);
1779
+ return next;
1780
+ }
1781
+ function startOfUtcMonth(date) {
1782
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
1783
+ }
1784
+ function addUtcMonths(date, months) {
1785
+ return new Date(
1786
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
1787
+ );
1788
+ }
1789
+ function startOfUtcIsoWeek(date) {
1790
+ const day = date.getUTCDay() || 7;
1791
+ return addUtcDays(startOfUtcDay(date), 1 - day);
1792
+ }
1793
+ function getUtcIsoWeekPeriod(date) {
1794
+ const day = date.getUTCDay() || 7;
1795
+ const thursday = addUtcDays(startOfUtcDay(date), 4 - day);
1796
+ const isoYear = thursday.getUTCFullYear();
1797
+ const yearStart = new Date(Date.UTC(isoYear, 0, 1));
1798
+ const isoWeek = Math.ceil(
1799
+ ((thursday.getTime() - yearStart.getTime()) / MS_PER_DAY + 1) / 7
1800
+ );
1801
+ return `${isoYear}-W${String(isoWeek).padStart(2, "0")}`;
1802
+ }
1803
+ function formatUtcDatePeriod(date) {
1804
+ return date.toISOString().slice(0, 10);
1805
+ }
1806
+ function formatUtcHourPeriod(date) {
1807
+ return date.toISOString().slice(0, 13).replace("T", " ");
1808
+ }
1809
+ function formatUtcMonthPeriod(date) {
1810
+ return date.toISOString().slice(0, 7);
1811
+ }
1812
+ function periodFromDate(granularity, date = /* @__PURE__ */ new Date()) {
1813
+ if (granularity === "day") {
1814
+ return {
1815
+ granularity,
1816
+ period: formatUtcDatePeriod(startOfUtcDay(date))
1817
+ };
1818
+ }
1819
+ if (granularity === "week") {
1820
+ return { granularity, period: getUtcIsoWeekPeriod(date) };
1821
+ }
1822
+ return { granularity, period: formatUtcMonthPeriod(startOfUtcMonth(date)) };
1823
+ }
1824
+ function currentPeriod() {
1825
+ return periodFromDate("day");
1826
+ }
1827
+ function periodToWindow(selection) {
1828
+ if (selection.granularity === "day") {
1829
+ const start2 = /* @__PURE__ */ new Date(`${selection.period}T00:00:00.000Z`);
1830
+ return { start: start2, end: addUtcDays(start2, 1) };
1831
+ }
1832
+ if (selection.granularity === "week") {
1833
+ const [yearText2, weekText] = selection.period.split("-W");
1834
+ const isoYear = Number(yearText2);
1835
+ const isoWeek = Number(weekText);
1836
+ const jan4 = new Date(Date.UTC(isoYear, 0, 4));
1837
+ const start2 = addUtcDays(startOfUtcIsoWeek(jan4), (isoWeek - 1) * 7);
1838
+ return { start: start2, end: addUtcDays(start2, 7) };
1839
+ }
1840
+ const [yearText, monthText] = selection.period.split("-");
1841
+ const start = new Date(
1842
+ Date.UTC(Number(yearText), Number(monthText) - 1, 1)
1843
+ );
1844
+ return { start, end: addUtcMonths(start, 1) };
1845
+ }
1846
+ function getPeriodBucketKeys(selection) {
1847
+ const { start, end } = periodToWindow(selection);
1848
+ const bucketKeys = [];
1849
+ const cursor = new Date(start);
1850
+ if (selection.granularity === "day") {
1851
+ while (cursor < end) {
1852
+ bucketKeys.push(`${formatUtcHourPeriod(cursor)}:00:00`);
1853
+ cursor.setUTCHours(cursor.getUTCHours() + 1);
1854
+ }
1855
+ return bucketKeys;
1856
+ }
1857
+ while (cursor < end) {
1858
+ bucketKeys.push(formatUtcDatePeriod(cursor));
1859
+ cursor.setUTCDate(cursor.getUTCDate() + 1);
1860
+ }
1861
+ return bucketKeys;
1862
+ }
1863
+ function periodBucketKeyToDate(bucketKey, granularity) {
1864
+ if (granularity === "day") {
1865
+ return /* @__PURE__ */ new Date(`${bucketKey.replace(" ", "T")}.000Z`);
1866
+ }
1867
+ return /* @__PURE__ */ new Date(`${bucketKey}T00:00:00.000Z`);
1868
+ }
1869
+ function isPeriodSelectable(selection, minDate = /* @__PURE__ */ new Date(0), maxDate = startOfUtcDay()) {
1870
+ const { start, end } = periodToWindow(selection);
1871
+ return end > minDate && start <= maxDate;
1872
+ }
1873
+
1296
1874
  // src/primitives/TabButton.tsx
1297
- var import_jsx_runtime18 = require("react/jsx-runtime");
1298
- var sizeClasses2 = {
1299
- medium: "polli:px-4 polli:py-1.5 polli:text-base",
1300
- small: "polli:px-3 polli:py-1.5 polli:text-sm"
1875
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1876
+ var sizeClasses = {
1877
+ md: "polli:px-4 polli:py-1.5 polli:text-base",
1878
+ sm: "polli:px-3 polli:py-1.5 polli:text-sm"
1879
+ };
1880
+ var variantClasses2 = {
1881
+ default: {
1882
+ base: "polli:border",
1883
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border",
1884
+ inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active"
1885
+ },
1886
+ ghost: {
1887
+ base: "polli:border polli:border-transparent",
1888
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong",
1889
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong"
1890
+ }
1301
1891
  };
1302
1892
  var TabButton = ({
1303
1893
  theme,
1304
1894
  active,
1305
1895
  onClick,
1306
1896
  children,
1307
- size = "medium",
1897
+ size = "md",
1898
+ variant = "default",
1308
1899
  ariaLabel,
1309
1900
  disabled = false,
1310
1901
  className
1311
1902
  }) => {
1312
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1903
+ const classes = variantClasses2[variant];
1904
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1313
1905
  "button",
1314
1906
  {
1315
1907
  type: "button",
@@ -1318,11 +1910,12 @@ var TabButton = ({
1318
1910
  "aria-label": ariaLabel,
1319
1911
  "aria-pressed": active,
1320
1912
  disabled,
1321
- className: cn2(
1322
- "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:border polli:font-medium polli:leading-normal polli:transition-all polli:duration-200",
1323
- active ? "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border" : "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active",
1913
+ className: cn(
1914
+ "polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-all polli:duration-200",
1915
+ classes.base,
1916
+ active ? classes.active : classes.inactive,
1324
1917
  disabled && "polli:cursor-not-allowed polli:opacity-50",
1325
- sizeClasses2[size],
1918
+ sizeClasses[size],
1326
1919
  className
1327
1920
  ),
1328
1921
  children
@@ -1330,8 +1923,8 @@ var TabButton = ({
1330
1923
  );
1331
1924
  };
1332
1925
 
1333
- // src/primitives/PeriodPicker.tsx
1334
- var import_jsx_runtime19 = require("react/jsx-runtime");
1926
+ // src/compositions/PeriodPicker.tsx
1927
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1335
1928
  var WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
1336
1929
  var MONTH_LABELS = [
1337
1930
  "Jan",
@@ -1347,7 +1940,7 @@ var MONTH_LABELS = [
1347
1940
  "Nov",
1348
1941
  "Dec"
1349
1942
  ];
1350
- var NAV_BUTTON = "polli:rounded-full polli:px-2 polli:py-1 polli:text-xs polli:font-semibold polli:text-theme-text-base polli:transition-colors polli:hover:bg-theme-bg-subtle";
1943
+ var NAV_BUTTON = "polli-control polli:rounded-full polli:px-2 polli:py-1 polli:text-xs polli:font-semibold polli:text-theme-text-base polli:transition-colors polli:hover:bg-theme-bg-subtle";
1351
1944
  function addUtcMonths2(date, months) {
1352
1945
  return new Date(
1353
1946
  Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
@@ -1367,6 +1960,42 @@ function sameUtcDay(left, right) {
1367
1960
  function periodDate(value) {
1368
1961
  return periodToWindow(value).start;
1369
1962
  }
1963
+ function selectionKey(value) {
1964
+ return `${value.granularity}:${value.period}`;
1965
+ }
1966
+ function formatMonthYear(date, month = "short") {
1967
+ return date.toLocaleDateString("en-US", {
1968
+ timeZone: "UTC",
1969
+ month,
1970
+ year: "numeric"
1971
+ });
1972
+ }
1973
+ function formatFullDate(date) {
1974
+ return date.toLocaleDateString("en-US", {
1975
+ timeZone: "UTC",
1976
+ month: "short",
1977
+ day: "numeric",
1978
+ year: "numeric"
1979
+ });
1980
+ }
1981
+ function formatWeekSummary(start, end) {
1982
+ const weekEnd = addUtcDays(end, -1);
1983
+ const sameMonth = start.getUTCFullYear() === weekEnd.getUTCFullYear() && start.getUTCMonth() === weekEnd.getUTCMonth();
1984
+ if (sameMonth) {
1985
+ const month = start.toLocaleDateString("en-US", {
1986
+ timeZone: "UTC",
1987
+ month: "short"
1988
+ });
1989
+ return `${month} ${start.getUTCDate()}-${weekEnd.getUTCDate()}, ${weekEnd.getUTCFullYear()}`;
1990
+ }
1991
+ return `${formatFullDate(start)} - ${formatFullDate(weekEnd)}`;
1992
+ }
1993
+ function formatPeriodSummary(value) {
1994
+ const { start, end } = periodToWindow(value);
1995
+ if (value.granularity === "day") return formatFullDate(start);
1996
+ if (value.granularity === "week") return formatWeekSummary(start, end);
1997
+ return formatMonthYear(start, "long");
1998
+ }
1370
1999
  function viewBounds(viewDate, granularity) {
1371
2000
  if (granularity === "month") {
1372
2001
  const start2 = new Date(Date.UTC(viewDate.getUTCFullYear(), 0, 1));
@@ -1386,9 +2015,18 @@ var PeriodPicker = ({
1386
2015
  }) => {
1387
2016
  const [open, setOpen] = (0, import_react7.useState)(false);
1388
2017
  const [viewDate, setViewDate] = (0, import_react7.useState)(() => periodDate(value));
2018
+ const [anchorDate, setAnchorDate] = (0, import_react7.useState)(() => periodDate(value));
2019
+ const emittedSelectionRef = (0, import_react7.useRef)(null);
1389
2020
  const { granularity, period } = value;
1390
2021
  (0, import_react7.useEffect)(() => {
1391
- setViewDate(periodDate({ granularity, period }));
2022
+ const currentSelectionKey = selectionKey({ granularity, period });
2023
+ if (emittedSelectionRef.current === currentSelectionKey) {
2024
+ emittedSelectionRef.current = null;
2025
+ return;
2026
+ }
2027
+ const nextAnchorDate = periodDate({ granularity, period });
2028
+ setAnchorDate(nextAnchorDate);
2029
+ setViewDate(nextAnchorDate);
1392
2030
  }, [granularity, period]);
1393
2031
  const dates = (0, import_react7.useMemo)(() => monthGridDates(viewDate), [viewDate]);
1394
2032
  const selectedWindow = periodToWindow(value);
@@ -1399,26 +2037,29 @@ var PeriodPicker = ({
1399
2037
  const nextBounds = viewBounds(nextViewDate, value.granularity);
1400
2038
  const previousDisabled = previousBounds.end <= minDate;
1401
2039
  const nextDisabled = nextBounds.start > today;
2040
+ const summaryLabel = formatPeriodSummary(value);
2041
+ const commitSelection = (selection, anchor) => {
2042
+ emittedSelectionRef.current = selectionKey(selection);
2043
+ setAnchorDate(anchor);
2044
+ setViewDate(anchor);
2045
+ onChange(selection);
2046
+ };
1402
2047
  const setGranularity = (granularity2) => {
1403
- onChange(periodFromDate(granularity2, periodDate(value)));
2048
+ commitSelection(periodFromDate(granularity2, anchorDate), anchorDate);
1404
2049
  };
1405
2050
  const selectDate = (date) => {
1406
- onChange(periodFromDate(value.granularity, date));
2051
+ commitSelection(periodFromDate(value.granularity, date), date);
1407
2052
  setOpen(false);
1408
2053
  };
1409
- const viewLabel = value.granularity === "month" ? String(viewDate.getUTCFullYear()) : viewDate.toLocaleDateString("en-US", {
1410
- timeZone: "UTC",
1411
- month: "long",
1412
- year: "numeric"
1413
- });
1414
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2054
+ const viewLabel = value.granularity === "month" ? String(viewDate.getUTCFullYear()) : formatMonthYear(viewDate, "long");
2055
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1415
2056
  "div",
1416
2057
  {
1417
2058
  "data-theme": theme,
1418
2059
  className: "polli:flex polli:flex-wrap polli:items-center polli:gap-2",
1419
2060
  children: [
1420
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:flex polli:flex-wrap polli:gap-1.5", children: ["day", "week", "month"].map(
1421
- (granularity2) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2061
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "polli:flex polli:flex-wrap polli:gap-1.5", children: ["day", "week", "month"].map(
2062
+ (granularity2) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1422
2063
  TabButton,
1423
2064
  {
1424
2065
  active: value.granularity === granularity2,
@@ -1428,55 +2069,55 @@ var PeriodPicker = ({
1428
2069
  granularity2
1429
2070
  )
1430
2071
  ) }),
1431
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2072
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1432
2073
  Dropdown,
1433
2074
  {
1434
2075
  theme,
1435
2076
  open,
1436
2077
  onOpenChange: setOpen,
1437
- className: "polli:w-[304px] polli:rounded-xl polli:p-3",
1438
- trigger: (isOpen) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2078
+ className: "polli:w-[320px] polli:rounded-xl polli:p-3.5",
2079
+ trigger: (isOpen) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1439
2080
  "button",
1440
2081
  {
1441
2082
  type: "button",
1442
- "aria-label": `Select period, current ${formatPeriodLabel(value)}`,
1443
- className: cn2(
1444
- "polli:inline-flex polli:min-w-[150px] polli:items-center polli:justify-between polli:gap-2 polli:rounded-full polli:border polli:px-4 polli:pt-1.5 polli:pb-2 polli:text-left polli:text-base polli:font-medium polli:leading-normal",
2083
+ "aria-label": `Select period, current ${summaryLabel}`,
2084
+ className: cn(
2085
+ "polli-control polli:inline-flex polli:w-[19rem] polli:max-w-full polli:items-center polli:justify-between polli:gap-2 polli:rounded-full polli:border polli:px-5 polli:pt-2 polli:pb-2.5 polli:text-left polli:text-base polli:font-medium polli:leading-normal",
1445
2086
  "polli:border-theme-border polli:bg-theme-bg-subtle polli:text-theme-text-base",
1446
2087
  "polli:transition-all polli:duration-200 polli:ease-out polli:hover:bg-theme-bg-pale",
1447
2088
  isOpen && "polli:bg-theme-bg-active polli:text-theme-text-strong polli:shadow-sm"
1448
2089
  ),
1449
2090
  children: [
1450
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: formatPeriodLabel(value) }),
1451
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronIcon, { expanded: isOpen })
2091
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "polli:truncate", children: summaryLabel }),
2092
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChevronIcon, { expanded: isOpen })
1452
2093
  ]
1453
2094
  }
1454
2095
  ),
1455
2096
  children: [
1456
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "polli:mb-3 polli:flex polli:items-center polli:justify-between", children: [
1457
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2097
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "polli:mb-3 polli:flex polli:items-center polli:justify-between", children: [
2098
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1458
2099
  "button",
1459
2100
  {
1460
2101
  type: "button",
1461
- "aria-label": value.granularity === "month" ? "Previous year" : "Previous month",
2102
+ "aria-label": "Previous",
1462
2103
  disabled: previousDisabled,
1463
2104
  onClick: () => setViewDate(previousViewDate),
1464
- className: cn2(
2105
+ className: cn(
1465
2106
  NAV_BUTTON,
1466
2107
  previousDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1467
2108
  ),
1468
2109
  children: "<"
1469
2110
  }
1470
2111
  ),
1471
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:text-sm polli:font-bold polli:text-theme-text-base", children: viewLabel }),
1472
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2112
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "polli:text-base polli:font-bold polli:text-theme-text-base", children: viewLabel }),
2113
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1473
2114
  "button",
1474
2115
  {
1475
2116
  type: "button",
1476
- "aria-label": value.granularity === "month" ? "Next year" : "Next month",
2117
+ "aria-label": "Next",
1477
2118
  disabled: nextDisabled,
1478
2119
  onClick: () => setViewDate(nextViewDate),
1479
- className: cn2(
2120
+ className: cn(
1480
2121
  NAV_BUTTON,
1481
2122
  nextDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1482
2123
  ),
@@ -1484,7 +2125,7 @@ var PeriodPicker = ({
1484
2125
  }
1485
2126
  )
1486
2127
  ] }),
1487
- value.granularity === "month" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:grid polli:grid-cols-3 polli:gap-1.5", children: MONTH_LABELS.map((label, monthIndex) => {
2128
+ value.granularity === "month" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "polli:grid polli:grid-cols-3 polli:gap-1.5", children: MONTH_LABELS.map((label, monthIndex) => {
1488
2129
  const date = new Date(
1489
2130
  Date.UTC(
1490
2131
  viewDate.getUTCFullYear(),
@@ -1503,32 +2144,32 @@ var PeriodPicker = ({
1503
2144
  year: "numeric"
1504
2145
  });
1505
2146
  const selected = date.getUTCFullYear() === selectedWindow.start.getUTCFullYear() && date.getUTCMonth() === selectedWindow.start.getUTCMonth();
1506
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2147
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1507
2148
  "button",
1508
2149
  {
1509
2150
  type: "button",
1510
2151
  "aria-label": ariaLabel,
1511
2152
  disabled: !selectable,
1512
2153
  onClick: () => selectDate(date),
1513
- className: cn2(
1514
- "polli:rounded-lg polli:px-3 polli:py-2 polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1515
- selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1516
- !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
2154
+ className: cn(
2155
+ "polli-control polli:rounded-lg polli:px-3 polli:py-2 polli:text-sm polli:font-medium polli:transition-colors polli:duration-150",
2156
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-ink-700 polli:hover:bg-theme-bg-subtle",
2157
+ !selectable && "polli:cursor-not-allowed polli:text-ink-300 polli:hover:bg-transparent"
1517
2158
  ),
1518
2159
  children: label
1519
2160
  },
1520
2161
  label
1521
2162
  );
1522
- }) }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1523
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:mb-1 polli:grid polli:grid-cols-7 polli:gap-1 polli:text-center polli:text-micro polli:font-bold polli:uppercase polli:text-gray-400", children: WEEKDAY_LABELS.map((label) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: label }, label)) }),
1524
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "polli:grid polli:grid-cols-7 polli:gap-1", children: dates.map((date) => {
2163
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
2164
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "polli:mb-1 polli:grid polli:grid-cols-7 polli:gap-1 polli:text-center polli:text-xs polli:font-bold polli:uppercase polli:text-ink-400", children: WEEKDAY_LABELS.map((label) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: label }, label)) }),
2165
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "polli:grid polli:grid-cols-7 polli:gap-1", children: dates.map((date) => {
1525
2166
  const inCurrentMonth = date.getUTCMonth() === viewDate.getUTCMonth();
1526
2167
  const selectable = isPeriodSelectable(
1527
2168
  periodFromDate(value.granularity, date),
1528
2169
  minDate,
1529
2170
  today
1530
2171
  );
1531
- const ariaLabel = value.granularity === "week" ? `Select week ${formatPeriodLabel(periodFromDate("week", date))}` : `Select ${date.toLocaleDateString(
2172
+ const ariaLabel = value.granularity === "week" ? `Select ${formatPeriodSummary(periodFromDate("week", date))}` : `Select ${date.toLocaleDateString(
1532
2173
  "en-US",
1533
2174
  {
1534
2175
  timeZone: "UTC",
@@ -1539,19 +2180,19 @@ var PeriodPicker = ({
1539
2180
  }
1540
2181
  )}`;
1541
2182
  const selected = value.granularity === "day" ? sameUtcDay(date, selectedWindow.start) : date >= selectedWindow.start && date < selectedWindow.end;
1542
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2183
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1543
2184
  "button",
1544
2185
  {
1545
2186
  type: "button",
1546
2187
  "aria-label": ariaLabel,
1547
2188
  disabled: !selectable,
1548
2189
  onClick: () => selectDate(date),
1549
- className: cn2(
1550
- "polli:aspect-square polli:rounded-lg polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1551
- !inCurrentMonth && "polli:text-gray-300",
2190
+ className: cn(
2191
+ "polli-control polli:aspect-square polli:rounded-lg polli:text-sm polli:font-medium polli:transition-colors polli:duration-150",
2192
+ !inCurrentMonth && "polli:text-ink-300",
1552
2193
  sameUtcDay(date, today) && "polli:ring-1 polli:ring-theme-border",
1553
- selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1554
- !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
2194
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-ink-700 polli:hover:bg-theme-bg-subtle",
2195
+ !selectable && "polli:cursor-not-allowed polli:text-ink-300 polli:hover:bg-transparent"
1555
2196
  ),
1556
2197
  children: date.getUTCDate()
1557
2198
  },
@@ -1567,58 +2208,517 @@ var PeriodPicker = ({
1567
2208
  );
1568
2209
  };
1569
2210
 
1570
- // src/primitives/Surface.tsx
1571
- var import_jsx_runtime20 = require("react/jsx-runtime");
1572
- var variantClasses = {
1573
- panel: "polli:rounded-2xl polli:border polli:border-theme-border polli:bg-theme-bg-subtle polli:p-6",
1574
- card: "polli:rounded-xl polli:bg-surface-white polli:p-4",
1575
- "card-themed": "polli:rounded-xl polli:bg-theme-bg-pale polli:p-4"
2211
+ // src/compositions/Prose.tsx
2212
+ var import_react_markdown2 = __toESM(require("react-markdown"), 1);
2213
+ var import_rehype_slug = __toESM(require("rehype-slug"), 1);
2214
+ var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
2215
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2216
+ var components2 = {
2217
+ h1: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2218
+ "h1",
2219
+ {
2220
+ className: headingClassName("title", "polli:mt-0 polli:mb-5"),
2221
+ ...props
2222
+ }
2223
+ ),
2224
+ h2: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2225
+ "h2",
2226
+ {
2227
+ className: headingClassName("section", "polli:mt-8 polli:mb-3"),
2228
+ ...props
2229
+ }
2230
+ ),
2231
+ h3: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2232
+ "h3",
2233
+ {
2234
+ className: headingClassName("subsection", "polli:mt-6 polli:mb-2"),
2235
+ ...props
2236
+ }
2237
+ ),
2238
+ p: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "polli:my-4 polli:leading-relaxed", ...props }),
2239
+ a: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2240
+ "a",
2241
+ {
2242
+ className: "polli-control polli:rounded-sm polli:font-semibold polli:text-theme-text-strong polli:underline polli:decoration-theme-border polli:decoration-2 polli:underline-offset-3 polli:hover:decoration-theme-text-soft",
2243
+ ...props
2244
+ }
2245
+ ),
2246
+ ul: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2247
+ "ul",
2248
+ {
2249
+ className: "polli:my-4 polli:list-disc polli:pl-6 polli:leading-relaxed",
2250
+ ...props
2251
+ }
2252
+ ),
2253
+ ol: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2254
+ "ol",
2255
+ {
2256
+ className: "polli:my-4 polli:list-decimal polli:pl-6 polli:leading-relaxed",
2257
+ ...props
2258
+ }
2259
+ ),
2260
+ blockquote: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2261
+ "blockquote",
2262
+ {
2263
+ className: "polli:my-4 polli:border-l-4 polli:border-theme-border polli:pl-4 polli:text-theme-text-soft",
2264
+ ...props
2265
+ }
2266
+ ),
2267
+ code: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2268
+ "code",
2269
+ {
2270
+ className: "polli:rounded polli:bg-theme-bg-active polli:px-1 polli:py-0.5 polli:font-pixel polli:text-sm",
2271
+ ...props
2272
+ }
2273
+ ),
2274
+ pre: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2275
+ "pre",
2276
+ {
2277
+ className: "polli:my-4 polli:overflow-x-auto polli:rounded-lg polli:bg-theme-bg-active polli:p-4",
2278
+ ...props
2279
+ }
2280
+ ),
2281
+ table: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2282
+ "table",
2283
+ {
2284
+ className: "polli:my-4 polli:w-full polli:border-collapse polli:text-sm",
2285
+ ...props
2286
+ }
2287
+ ),
2288
+ th: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2289
+ "th",
2290
+ {
2291
+ className: "polli:border polli:border-theme-border polli:px-3 polli:py-2 polli:text-left polli:font-semibold",
2292
+ ...props
2293
+ }
2294
+ ),
2295
+ td: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2296
+ "td",
2297
+ {
2298
+ className: "polli:border polli:border-theme-border polli:px-3 polli:py-2",
2299
+ ...props
2300
+ }
2301
+ ),
2302
+ hr: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("hr", { className: "polli:my-6 polli:border-theme-border", ...props })
2303
+ };
2304
+ function Prose({ children, className }) {
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2306
+ "div",
2307
+ {
2308
+ className: cn(
2309
+ "polli:font-body polli:text-theme-text-base polli:leading-relaxed",
2310
+ className
2311
+ ),
2312
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2313
+ import_react_markdown2.default,
2314
+ {
2315
+ remarkPlugins: [import_remark_gfm2.default],
2316
+ rehypePlugins: [import_rehype_slug.default],
2317
+ components: components2,
2318
+ children
2319
+ }
2320
+ )
2321
+ }
2322
+ );
2323
+ }
2324
+
2325
+ // src/compositions/Section.tsx
2326
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2327
+ var Section = ({
2328
+ title,
2329
+ theme,
2330
+ id,
2331
+ framed = false,
2332
+ intro,
2333
+ action,
2334
+ actionClassName,
2335
+ panelClassName,
2336
+ titleClassName,
2337
+ children,
2338
+ className
2339
+ }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
2340
+ "section",
2341
+ {
2342
+ id,
2343
+ className: cn(
2344
+ "polli:flex polli:scroll-mt-10 polli:flex-col polli:gap-4",
2345
+ className
2346
+ ),
2347
+ children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("header", { className: "polli:flex polli:flex-wrap polli:items-center polli:justify-between polli:gap-3 polli:px-1", children: [
2349
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2350
+ Heading,
2351
+ {
2352
+ as: "h2",
2353
+ "data-theme": theme,
2354
+ size: "section",
2355
+ className: cn("polli:text-left", titleClassName),
2356
+ children: title
2357
+ }
2358
+ ),
2359
+ action && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn("polli:shrink-0", actionClassName), children: action })
2360
+ ] }),
2361
+ framed ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
2362
+ Surface,
2363
+ {
2364
+ variant: "panel",
2365
+ theme,
2366
+ className: cn(
2367
+ "polli:flex polli:flex-col polli:gap-5",
2368
+ panelClassName
2369
+ ),
2370
+ children: [
2371
+ intro && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Text, { as: "div", className: "polli:max-w-2xl", children: intro }),
2372
+ children
2373
+ ]
2374
+ }
2375
+ ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
2376
+ intro && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2377
+ Text,
2378
+ {
2379
+ as: "div",
2380
+ "data-theme": theme,
2381
+ className: "polli:max-w-2xl",
2382
+ children: intro
2383
+ }
2384
+ ),
2385
+ children
2386
+ ] })
2387
+ ]
2388
+ }
2389
+ );
2390
+
2391
+ // src/compositions/StatCard.tsx
2392
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2393
+ var valueVariantClasses = {
2394
+ stat: "polli:min-h-8 polli:text-2xl polli:font-bold polli:leading-tight polli:tabular-nums polli:text-theme-text-strong",
2395
+ fact: "polli:text-sm polli:leading-6 polli:text-theme-text-soft"
1576
2396
  };
1577
- var Surface = ({
2397
+ var StatCard = ({
2398
+ label,
2399
+ value,
2400
+ detail,
2401
+ variant = "stat",
1578
2402
  theme,
1579
- variant = "card",
2403
+ className,
2404
+ labelClassName,
2405
+ valueClassName,
2406
+ detailClassName
2407
+ }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { "data-theme": theme, className: cn("polli:text-sm", className), children: [
2408
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2409
+ Text,
2410
+ {
2411
+ as: "div",
2412
+ size: "micro",
2413
+ tone: "strong",
2414
+ weight: "bold",
2415
+ className: cn(
2416
+ "polli:uppercase polli:tracking-wide",
2417
+ labelClassName
2418
+ ),
2419
+ children: label
2420
+ }
2421
+ ),
2422
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2423
+ "div",
2424
+ {
2425
+ className: cn(
2426
+ "polli:mt-1 polli:break-words",
2427
+ valueVariantClasses[variant],
2428
+ valueClassName
2429
+ ),
2430
+ children: value
2431
+ }
2432
+ ),
2433
+ detail && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2434
+ Text,
2435
+ {
2436
+ as: "div",
2437
+ size: "xs",
2438
+ tone: "soft",
2439
+ className: cn("polli:mt-2", detailClassName),
2440
+ children: detail
2441
+ }
2442
+ )
2443
+ ] });
2444
+
2445
+ // src/lib/cn-app.ts
2446
+ var import_clsx2 = require("clsx");
2447
+ var import_tailwind_merge2 = require("tailwind-merge");
2448
+ function cn2(...inputs) {
2449
+ return (0, import_tailwind_merge2.twMerge)((0, import_clsx2.clsx)(...inputs));
2450
+ }
2451
+
2452
+ // src/lib/use-scroll-lock.ts
2453
+ var import_react8 = require("react");
2454
+ function useScrollLock(enabled = true) {
2455
+ (0, import_react8.useEffect)(() => {
2456
+ if (!enabled) return;
2457
+ const originalBody = document.body.style.overflow;
2458
+ const originalHtml = document.documentElement.style.overflow;
2459
+ document.body.style.overflow = "hidden";
2460
+ document.documentElement.style.overflow = "hidden";
2461
+ return () => {
2462
+ document.body.style.overflow = originalBody;
2463
+ document.documentElement.style.overflow = originalHtml;
2464
+ };
2465
+ }, [enabled]);
2466
+ }
2467
+
2468
+ // src/primitives/ButtonGroup.tsx
2469
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2470
+ var ButtonGroup = ({
2471
+ wrap = true,
1580
2472
  className,
1581
2473
  children,
2474
+ role = "group",
1582
2475
  ...rest
1583
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2476
+ }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1584
2477
  "div",
1585
2478
  {
1586
2479
  ...rest,
1587
- "data-theme": theme,
1588
- className: cn2("polli:min-w-0", variantClasses[variant], className),
2480
+ role,
2481
+ className: cn(
2482
+ "polli:flex polli:min-w-0 polli:items-center polli:gap-1.5",
2483
+ wrap ? "polli:flex-wrap" : "polli:flex-nowrap",
2484
+ className
2485
+ ),
1589
2486
  children
1590
2487
  }
1591
2488
  );
1592
2489
 
1593
- // src/primitives/Section.tsx
1594
- var import_jsx_runtime21 = require("react/jsx-runtime");
1595
- var Section = ({
2490
+ // src/primitives/Chip.tsx
2491
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2492
+ var chipSizes = {
2493
+ sm: "polli:px-2 polli:py-0.5 polli:text-xs",
2494
+ md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
2495
+ lg: "polli:px-3 polli:py-1 polli:text-sm"
2496
+ };
2497
+ var intentClasses4 = {
2498
+ news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
2499
+ alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
2500
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
2501
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
2502
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
2503
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
2504
+ };
2505
+ var Chip = ({
2506
+ theme,
2507
+ intent,
2508
+ size = "md",
2509
+ className,
2510
+ children,
2511
+ ...rest
2512
+ }) => {
2513
+ const intentClass = intent ? intentClasses4[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
2514
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2515
+ "span",
2516
+ {
2517
+ ...rest,
2518
+ "data-theme": theme,
2519
+ className: cn(
2520
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
2521
+ chipSizes[size],
2522
+ intentClass,
2523
+ className
2524
+ ),
2525
+ children
2526
+ }
2527
+ );
2528
+ };
2529
+
2530
+ // src/primitives/Dialog.tsx
2531
+ var import_dialog = require("@ark-ui/react/dialog");
2532
+ var import_portal2 = require("@ark-ui/react/portal");
2533
+ var import_react9 = require("react");
2534
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2535
+ var sizeClasses2 = {
2536
+ sm: "polli:max-w-md",
2537
+ md: "polli:max-w-xl",
2538
+ lg: "polli:max-w-2xl"
2539
+ };
2540
+ var Dialog = ({
2541
+ open,
2542
+ onOpenChange,
2543
+ trigger,
2544
+ triggerAsChild = false,
2545
+ triggerClassName,
1596
2546
  title,
2547
+ titleClassName,
2548
+ ariaLabel,
2549
+ labelledBy,
2550
+ theme = "blue",
2551
+ size = "md",
2552
+ showBackdrop = true,
2553
+ backdropClassName,
2554
+ positionerClassName,
2555
+ contentClassName,
2556
+ children
2557
+ }) => {
2558
+ const contentRef = (0, import_react9.useRef)(null);
2559
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2560
+ import_dialog.Dialog.Root,
2561
+ {
2562
+ open,
2563
+ initialFocusEl: () => contentRef.current,
2564
+ onOpenChange: (details) => onOpenChange?.(details.open),
2565
+ children: [
2566
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2567
+ import_dialog.Dialog.Trigger,
2568
+ {
2569
+ asChild: triggerAsChild,
2570
+ className: triggerClassName,
2571
+ children: trigger
2572
+ }
2573
+ ),
2574
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_portal2.Portal, { children: [
2575
+ showBackdrop && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2576
+ import_dialog.Dialog.Backdrop,
2577
+ {
2578
+ className: cn(
2579
+ "polli:fixed polli:inset-0 polli:z-[100] polli:bg-ink-950/50",
2580
+ backdropClassName
2581
+ )
2582
+ }
2583
+ ),
2584
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2585
+ import_dialog.Dialog.Positioner,
2586
+ {
2587
+ "data-theme": theme,
2588
+ className: cn(
2589
+ "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
2590
+ positionerClassName
2591
+ ),
2592
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2593
+ import_dialog.Dialog.Content,
2594
+ {
2595
+ ref: contentRef,
2596
+ "data-theme": theme,
2597
+ "aria-label": ariaLabel,
2598
+ "aria-labelledby": labelledBy,
2599
+ className: cn(
2600
+ "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-surface-opaque polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none",
2601
+ sizeClasses2[size],
2602
+ contentClassName
2603
+ ),
2604
+ children: [
2605
+ title && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2606
+ DialogTitle,
2607
+ {
2608
+ className: cn(
2609
+ "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
2610
+ titleClassName
2611
+ ),
2612
+ children: title
2613
+ }
2614
+ ),
2615
+ children
2616
+ ]
2617
+ }
2618
+ )
2619
+ }
2620
+ )
2621
+ ] })
2622
+ ]
2623
+ }
2624
+ );
2625
+ };
2626
+ var DialogTitle = import_dialog.Dialog.Title;
2627
+
2628
+ // src/primitives/DropdownItem.tsx
2629
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2630
+ function DropdownItem({
2631
+ as,
2632
+ className,
2633
+ children,
2634
+ ...rest
2635
+ }) {
2636
+ const Component = as || "button";
2637
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2638
+ Component,
2639
+ {
2640
+ ...Component === "button" ? { type: "button" } : void 0,
2641
+ ...rest,
2642
+ className: cn(
2643
+ "polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover",
2644
+ className
2645
+ ),
2646
+ children
2647
+ }
2648
+ );
2649
+ }
2650
+
2651
+ // src/primitives/Field.tsx
2652
+ var import_field = require("@ark-ui/react/field");
2653
+
2654
+ // src/primitives/InlineLink.tsx
2655
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2656
+ function isExternalHref2(href) {
2657
+ return typeof href === "string" && /^https?:\/\//.test(href);
2658
+ }
2659
+ function InlineLink({
2660
+ as,
1597
2661
  theme,
1598
- id,
1599
- framed = false,
1600
- action,
1601
- actionClassName,
2662
+ external,
2663
+ showIcon = true,
2664
+ className,
1602
2665
  children,
1603
- className
1604
- }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("section", { id, className: cn2("scroll-mt-10 space-y-2", className), children: [
1605
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-1", children: [
1606
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1607
- "h2",
1608
- {
1609
- "data-theme": theme,
1610
- className: "text-left text-lg font-semibold sm:text-xl text-theme-text-strong",
1611
- children: title
1612
- }
1613
- ),
1614
- action && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn2("shrink-0", actionClassName), children: action })
1615
- ] }),
1616
- framed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Surface, { variant: "panel", theme, children }) : children
1617
- ] });
2666
+ ...linkProps
2667
+ }) {
2668
+ const Component = as || "a";
2669
+ const isExternal = external ?? isExternalHref2(linkProps.href);
2670
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2671
+ Component,
2672
+ {
2673
+ "data-theme": theme,
2674
+ target: isExternal ? "_blank" : void 0,
2675
+ rel: isExternal ? "noopener noreferrer" : void 0,
2676
+ className: cn(
2677
+ "polli-control polli:inline-flex polli:items-center polli:gap-1 polli:rounded-sm polli:font-semibold polli:text-theme-text-strong",
2678
+ "polli:underline polli:decoration-theme-border polli:decoration-2 polli:underline-offset-3",
2679
+ "polli:transition-colors polli:hover:text-theme-text-soft polli:hover:decoration-theme-text-soft",
2680
+ className
2681
+ ),
2682
+ ...linkProps,
2683
+ children: [
2684
+ children,
2685
+ showIcon && isExternal && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2686
+ ExternalLinkIcon,
2687
+ {
2688
+ "aria-hidden": "true",
2689
+ className: "polli:h-3.5 polli:w-3.5 polli:shrink-0 polli:opacity-65"
2690
+ }
2691
+ )
2692
+ ]
2693
+ }
2694
+ );
2695
+ }
2696
+
2697
+ // src/primitives/Input.tsx
2698
+ var import_react10 = require("react");
2699
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2700
+ var Input = (0, import_react10.forwardRef)(
2701
+ ({ className, error, hideNumberSteppers, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2702
+ "input",
2703
+ {
2704
+ ref,
2705
+ "data-error": error ? "true" : void 0,
2706
+ className: cn(
2707
+ "polli-input polli:px-3 polli:py-2 polli:border polli:rounded-lg",
2708
+ "polli:text-ink-950",
2709
+ "polli:transition-colors",
2710
+ "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
2711
+ hideNumberSteppers && "polli-input-number-clean",
2712
+ className
2713
+ ),
2714
+ ...props
2715
+ }
2716
+ )
2717
+ );
1618
2718
 
1619
2719
  // src/primitives/Slider.tsx
1620
- var import_react8 = require("react");
1621
- var import_jsx_runtime22 = require("react/jsx-runtime");
2720
+ var import_react11 = require("react");
2721
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1622
2722
  var toNumber = (value) => {
1623
2723
  if (typeof value === "number") return value;
1624
2724
  if (typeof value !== "string" || value.trim() === "") return void 0;
@@ -1645,7 +2745,7 @@ var getProgressPercent = ({
1645
2745
  (numericValue - numericMin) / (numericMax - numericMin) * 100
1646
2746
  );
1647
2747
  };
1648
- var Slider = (0, import_react8.forwardRef)(
2748
+ var Slider = (0, import_react11.forwardRef)(
1649
2749
  ({ className, defaultValue, max, min, progress, style, value, ...props }, ref) => {
1650
2750
  const progressPercent = getProgressPercent({
1651
2751
  progress,
@@ -1658,7 +2758,7 @@ var Slider = (0, import_react8.forwardRef)(
1658
2758
  ...style,
1659
2759
  ...progressPercent === void 0 ? null : { "--polli-slider-progress": `${progressPercent}%` }
1660
2760
  };
1661
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2761
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1662
2762
  "input",
1663
2763
  {
1664
2764
  ref,
@@ -1668,63 +2768,19 @@ var Slider = (0, import_react8.forwardRef)(
1668
2768
  value,
1669
2769
  defaultValue,
1670
2770
  style: sliderStyle,
1671
- className: cn2("polli-slider", className),
2771
+ className: cn("polli-slider", className),
1672
2772
  ...props
1673
2773
  }
1674
2774
  );
1675
2775
  }
1676
2776
  );
1677
2777
 
1678
- // src/primitives/StatCard.tsx
1679
- var import_jsx_runtime23 = require("react/jsx-runtime");
1680
- var StatCard = ({
1681
- label,
1682
- value,
1683
- detail,
1684
- theme,
1685
- className,
1686
- labelClassName,
1687
- valueClassName,
1688
- detailClassName
1689
- }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { "data-theme": theme, className: cn2("polli:text-sm", className), children: [
1690
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1691
- "div",
1692
- {
1693
- className: cn2(
1694
- "polli:text-micro polli:font-bold polli:uppercase polli:tracking-wide polli:text-theme-text-strong",
1695
- labelClassName
1696
- ),
1697
- children: label
1698
- }
1699
- ),
1700
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1701
- "div",
1702
- {
1703
- className: cn2(
1704
- "polli:mt-1 polli:min-h-8 polli:break-words polli:text-2xl polli:font-bold polli:leading-tight polli:tabular-nums polli:text-theme-text-strong",
1705
- valueClassName
1706
- ),
1707
- children: value
1708
- }
1709
- ),
1710
- detail && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1711
- "div",
1712
- {
1713
- className: cn2(
1714
- "polli:mt-2 polli:text-xs polli:text-theme-text-soft",
1715
- detailClassName
1716
- ),
1717
- children: detail
1718
- }
1719
- )
1720
- ] });
1721
-
1722
2778
  // src/primitives/Switch.tsx
1723
- var import_jsx_runtime24 = require("react/jsx-runtime");
2779
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1724
2780
  var trackClasses = {
1725
- off: "polli:bg-gray-200",
1726
- on: "polli:bg-[oklch(0.88_0.12_158)]",
1727
- invalid: "polli:bg-[oklch(0.88_0.12_25)]"
2781
+ off: "polli:bg-ink-200",
2782
+ on: "polli:bg-intent-success-bg-light",
2783
+ invalid: "polli:bg-intent-danger-bg-light"
1728
2784
  };
1729
2785
  var Switch = ({
1730
2786
  checked,
@@ -1736,7 +2792,7 @@ var Switch = ({
1736
2792
  }) => {
1737
2793
  const effectiveStatus = status ?? (checked ? "on" : "off");
1738
2794
  const resolvedAriaLabel = ariaLabel ?? (checked ? "Turn off toggle" : "Turn on toggle");
1739
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2795
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1740
2796
  "button",
1741
2797
  {
1742
2798
  type: "button",
@@ -1745,16 +2801,16 @@ var Switch = ({
1745
2801
  "aria-label": resolvedAriaLabel,
1746
2802
  onClick: () => onChange(!checked),
1747
2803
  disabled,
1748
- className: cn2(
1749
- "polli:relative polli:inline-flex polli:h-7 polli:w-12 polli:shrink-0 polli:items-center polli:rounded-full polli:transition polli:disabled:cursor-not-allowed polli:disabled:opacity-60",
2804
+ className: cn(
2805
+ "polli-control polli:relative polli:inline-flex polli:h-7 polli:w-12 polli:shrink-0 polli:items-center polli:rounded-full polli:transition polli:disabled:cursor-not-allowed polli:disabled:opacity-60",
1750
2806
  trackClasses[effectiveStatus],
1751
2807
  className
1752
2808
  ),
1753
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2809
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1754
2810
  "span",
1755
2811
  {
1756
- className: cn2(
1757
- "polli:inline-block polli:h-5 polli:w-5 polli:rounded-full polli:bg-white polli:shadow-sm polli:transition-transform",
2812
+ className: cn(
2813
+ "polli:inline-block polli:h-5 polli:w-5 polli:rounded-full polli:bg-surface-opaque polli:shadow-sm polli:transition-transform",
1758
2814
  checked ? "polli:translate-x-6" : "polli:translate-x-1"
1759
2815
  )
1760
2816
  }
@@ -1764,7 +2820,7 @@ var Switch = ({
1764
2820
  };
1765
2821
 
1766
2822
  // src/primitives/Table.tsx
1767
- var import_jsx_runtime25 = require("react/jsx-runtime");
2823
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1768
2824
  var alignClasses = {
1769
2825
  left: "polli:text-left",
1770
2826
  center: "polli:text-center",
@@ -1776,42 +2832,42 @@ var rowIntentClasses = {
1776
2832
  warning: "polli:bg-intent-warning-bg-light/65",
1777
2833
  danger: "polli:bg-intent-danger-bg-light/65"
1778
2834
  };
1779
- var Table = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2835
+ var Table = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1780
2836
  "table",
1781
2837
  {
1782
2838
  ...rest,
1783
- className: cn2(
2839
+ className: cn(
1784
2840
  "polli:w-full polli:border-collapse polli:text-sm",
1785
2841
  className
1786
2842
  )
1787
2843
  }
1788
2844
  );
1789
- var TableHead = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2845
+ var TableHead = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1790
2846
  "thead",
1791
2847
  {
1792
2848
  ...rest,
1793
- className: cn2(
1794
- "polli:bg-theme-bg-active polli:text-micro polli:text-theme-text-muted",
2849
+ className: cn(
2850
+ "polli:bg-transparent polli:text-micro polli:text-theme-text-muted",
1795
2851
  className
1796
2852
  )
1797
2853
  }
1798
2854
  );
1799
- var TableBody = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2855
+ var TableBody = ({ className, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1800
2856
  "tbody",
1801
2857
  {
1802
2858
  ...rest,
1803
- className: cn2("polli:divide-y polli:divide-theme-border/65", className)
2859
+ className: cn("polli:divide-y polli:divide-theme-border/65", className)
1804
2860
  }
1805
2861
  );
1806
2862
  var TableRow = ({
1807
2863
  intent = "default",
1808
2864
  className,
1809
2865
  ...rest
1810
- }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2866
+ }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1811
2867
  "tr",
1812
2868
  {
1813
2869
  ...rest,
1814
- className: cn2(
2870
+ className: cn(
1815
2871
  "polli:transition-colors polli:hover:bg-theme-bg-subtle",
1816
2872
  rowIntentClasses[intent],
1817
2873
  className
@@ -1827,11 +2883,11 @@ var TableHeaderCell = ({
1827
2883
  children,
1828
2884
  ...rest
1829
2885
  }) => {
1830
- const content = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
1831
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children }),
1832
- active && sortDirection && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": "true", children: sortDirection === "asc" ? "^" : "v" })
2886
+ const content = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
2887
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children }),
2888
+ active && sortDirection && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-hidden": "true", children: sortDirection === "asc" ? "^" : "v" })
1833
2889
  ] });
1834
- const classes = cn2(
2890
+ const classes = cn(
1835
2891
  "polli:px-3 polli:py-2 polli:font-bold polli:uppercase polli:tracking-wide",
1836
2892
  alignClasses[align],
1837
2893
  active && "polli:text-theme-text-strong",
@@ -1839,15 +2895,15 @@ var TableHeaderCell = ({
1839
2895
  className
1840
2896
  );
1841
2897
  if (!onSort) {
1842
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("th", { ...rest, className: classes, children: content });
2898
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("th", { ...rest, className: classes, children: content });
1843
2899
  }
1844
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("th", { ...rest, className: classes, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2900
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("th", { ...rest, className: classes, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1845
2901
  "button",
1846
2902
  {
1847
2903
  type: "button",
1848
2904
  onClick: onSort,
1849
- className: cn2(
1850
- "polli:inline-flex polli:w-full polli:items-center polli:gap-1 polli:bg-transparent polli:p-0 polli:font-bold polli:text-inherit",
2905
+ className: cn(
2906
+ "polli-control polli:inline-flex polli:w-full polli:items-center polli:gap-1 polli:bg-transparent polli:p-0 polli:font-bold polli:text-inherit",
1851
2907
  align === "right" && "polli:justify-end",
1852
2908
  align === "center" && "polli:justify-center"
1853
2909
  ),
@@ -1861,11 +2917,11 @@ var TableCell = ({
1861
2917
  muted = false,
1862
2918
  className,
1863
2919
  ...rest
1864
- }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2920
+ }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1865
2921
  "td",
1866
2922
  {
1867
2923
  ...rest,
1868
- className: cn2(
2924
+ className: cn(
1869
2925
  "polli:px-3 polli:py-2 polli:align-middle",
1870
2926
  alignClasses[align],
1871
2927
  numeric && "polli:tabular-nums",
@@ -1875,19 +2931,61 @@ var TableCell = ({
1875
2931
  }
1876
2932
  );
1877
2933
 
2934
+ // src/primitives/Textarea.tsx
2935
+ var import_react12 = require("react");
2936
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2937
+ var Textarea = (0, import_react12.forwardRef)(
2938
+ ({ className, error, rows = 4, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2939
+ "textarea",
2940
+ {
2941
+ ref,
2942
+ rows,
2943
+ "data-error": error ? "true" : void 0,
2944
+ className: cn(
2945
+ "polli-textarea polli:w-full polli:rounded-lg polli:border polli:px-3 polli:py-2",
2946
+ "polli:min-h-20 polli:resize-y polli:font-body polli:text-base",
2947
+ "polli:text-ink-950",
2948
+ "polli:transition-colors",
2949
+ "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
2950
+ className
2951
+ ),
2952
+ ...props
2953
+ }
2954
+ )
2955
+ );
2956
+ Textarea.displayName = "Textarea";
2957
+
2958
+ // src/theme-palette.json
2959
+ var theme_palette_default = {
2960
+ bgPale: {
2961
+ amber: "#fef3c7",
2962
+ blue: "#dbeafe",
2963
+ pink: "#fce7f3",
2964
+ coral: "#ffedd5",
2965
+ teal: "#ccfbf1",
2966
+ violet: "#ede9fe",
2967
+ emerald: "#d1fae5"
2968
+ },
2969
+ brandDark: "#110518"
2970
+ };
2971
+
1878
2972
  // src/theme.ts
1879
2973
  var themes = [
1880
2974
  "amber",
1881
2975
  "blue",
1882
2976
  "pink",
2977
+ "coral",
1883
2978
  "teal",
1884
2979
  "violet",
1885
- "green"
2980
+ "emerald"
1886
2981
  ];
2982
+ var themePalette = theme_palette_default;
1887
2983
  // Annotate the CommonJS export names for ESM import in node:
1888
2984
  0 && (module.exports = {
1889
2985
  Alert,
2986
+ AppHeader,
1890
2987
  AppIcon,
2988
+ AudioIcon,
1891
2989
  BeakerIcon,
1892
2990
  BookIcon,
1893
2991
  Button,
@@ -1897,6 +2995,7 @@ var themes = [
1897
2995
  Chip,
1898
2996
  ClipboardIcon,
1899
2997
  ClockIcon,
2998
+ CodeBlock,
1900
2999
  Collapsible,
1901
3000
  CopyButton,
1902
3001
  Dialog,
@@ -1904,21 +3003,31 @@ var themes = [
1904
3003
  DiscordIcon,
1905
3004
  DownloadIcon,
1906
3005
  Dropdown,
3006
+ DropdownItem,
1907
3007
  ExternalLinkButton,
1908
3008
  ExternalLinkIcon,
1909
3009
  Field,
3010
+ FileUpload,
1910
3011
  GenApiIcon,
1911
3012
  GitHubIcon,
3013
+ Heading,
1912
3014
  IconButton,
1913
3015
  ImageIcon,
1914
3016
  InfoTip,
3017
+ InlineLink,
1915
3018
  Input,
3019
+ LinkCard,
1916
3020
  LockIcon,
1917
3021
  MailIcon,
3022
+ Markdown,
1918
3023
  McpIcon,
3024
+ MediaPlaceholder,
1919
3025
  MenuIcon,
1920
3026
  MultiSelect,
3027
+ NavItem,
1921
3028
  PeriodPicker,
3029
+ PlusIcon,
3030
+ Prose,
1922
3031
  ScrollArea,
1923
3032
  Section,
1924
3033
  Slider,
@@ -1933,6 +3042,8 @@ var themes = [
1933
3042
  TableHeaderCell,
1934
3043
  TableRow,
1935
3044
  TerminalIcon,
3045
+ Text,
3046
+ Textarea,
1936
3047
  TokensIcon,
1937
3048
  Tooltip,
1938
3049
  TrendUpIcon,
@@ -1941,7 +3052,10 @@ var themes = [
1941
3052
  cn,
1942
3053
  currentPeriod,
1943
3054
  getPeriodBucketKeys,
3055
+ headingClassName,
1944
3056
  periodBucketKeyToDate,
3057
+ textClassName,
3058
+ themePalette,
1945
3059
  themes,
1946
3060
  useScrollLock
1947
3061
  });