@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.js CHANGED
@@ -1,179 +1,96 @@
1
- // src/lib/cn-app.ts
1
+ // src/lib/cn.ts
2
2
  import { clsx } from "clsx";
3
- import { twMerge } from "tailwind-merge";
3
+ import { extendTailwindMerge } from "tailwind-merge";
4
+ var twMerge = extendTailwindMerge({ prefix: "polli" });
4
5
  function cn(...inputs) {
5
6
  return twMerge(clsx(...inputs));
6
7
  }
7
8
 
8
- // src/lib/period.ts
9
- var MS_PER_DAY = 864e5;
10
- function startOfUtcDay(date = /* @__PURE__ */ new Date()) {
11
- return new Date(
12
- Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
13
- );
14
- }
15
- function addUtcDays(date, days) {
16
- const next = new Date(date);
17
- next.setUTCDate(next.getUTCDate() + days);
18
- return next;
19
- }
20
- function startOfUtcMonth(date) {
21
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
22
- }
23
- function addUtcMonths(date, months) {
24
- return new Date(
25
- Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
26
- );
27
- }
28
- function startOfUtcIsoWeek(date) {
29
- const day = date.getUTCDay() || 7;
30
- return addUtcDays(startOfUtcDay(date), 1 - day);
31
- }
32
- function getUtcIsoWeekPeriod(date) {
33
- const day = date.getUTCDay() || 7;
34
- const thursday = addUtcDays(startOfUtcDay(date), 4 - day);
35
- const isoYear = thursday.getUTCFullYear();
36
- const yearStart = new Date(Date.UTC(isoYear, 0, 1));
37
- const isoWeek = Math.ceil(
38
- ((thursday.getTime() - yearStart.getTime()) / MS_PER_DAY + 1) / 7
9
+ // src/primitives/Typography.tsx
10
+ import { jsx } from "react/jsx-runtime";
11
+ var headingSizeClasses = {
12
+ display: "polli:font-heading polli:text-5xl polli:leading-none",
13
+ title: "polli:font-heading polli:text-4xl polli:leading-none",
14
+ section: "polli:font-subheading polli:text-2xl polli:leading-tight",
15
+ subsection: "polli:font-subheading polli:text-xl polli:leading-tight",
16
+ card: "polli:font-subheading polli:text-lg polli:leading-tight"
17
+ };
18
+ var textSizeClasses = {
19
+ body: "polli:text-base polli:leading-relaxed",
20
+ sm: "polli:text-sm polli:leading-6",
21
+ xs: "polli:text-xs polli:leading-normal",
22
+ micro: "polli:text-micro polli:leading-normal"
23
+ };
24
+ var textToneClasses = {
25
+ base: "polli:text-theme-text-base",
26
+ strong: "polli:text-theme-text-strong",
27
+ soft: "polli:text-theme-text-soft",
28
+ muted: "polli:text-theme-text-muted"
29
+ };
30
+ var textWeightClasses = {
31
+ normal: "polli:font-normal",
32
+ medium: "polli:font-medium",
33
+ semibold: "polli:font-semibold",
34
+ bold: "polli:font-bold"
35
+ };
36
+ function headingClassName(size, className) {
37
+ return cn(
38
+ "polli:break-words polli:text-theme-text-strong",
39
+ headingSizeClasses[size],
40
+ className
39
41
  );
40
- return `${isoYear}-W${String(isoWeek).padStart(2, "0")}`;
41
- }
42
- function formatUtcDatePeriod(date) {
43
- return date.toISOString().slice(0, 10);
44
- }
45
- function formatUtcHourPeriod(date) {
46
- return date.toISOString().slice(0, 13).replace("T", " ");
47
- }
48
- function formatUtcMonthPeriod(date) {
49
- return date.toISOString().slice(0, 7);
50
- }
51
- function periodFromDate(granularity, date = /* @__PURE__ */ new Date()) {
52
- if (granularity === "day") {
53
- return {
54
- granularity,
55
- period: formatUtcDatePeriod(startOfUtcDay(date))
56
- };
57
- }
58
- if (granularity === "week") {
59
- return { granularity, period: getUtcIsoWeekPeriod(date) };
60
- }
61
- return { granularity, period: formatUtcMonthPeriod(startOfUtcMonth(date)) };
62
- }
63
- function currentPeriod() {
64
- return periodFromDate("day");
65
42
  }
66
- function periodToWindow(selection) {
67
- if (selection.granularity === "day") {
68
- const start2 = /* @__PURE__ */ new Date(`${selection.period}T00:00:00.000Z`);
69
- return { start: start2, end: addUtcDays(start2, 1) };
70
- }
71
- if (selection.granularity === "week") {
72
- const [yearText2, weekText] = selection.period.split("-W");
73
- const isoYear = Number(yearText2);
74
- const isoWeek = Number(weekText);
75
- const jan4 = new Date(Date.UTC(isoYear, 0, 4));
76
- const start2 = addUtcDays(startOfUtcIsoWeek(jan4), (isoWeek - 1) * 7);
77
- return { start: start2, end: addUtcDays(start2, 7) };
78
- }
79
- const [yearText, monthText] = selection.period.split("-");
80
- const start = new Date(
81
- Date.UTC(Number(yearText), Number(monthText) - 1, 1)
43
+ function textClassName({
44
+ size,
45
+ tone,
46
+ weight,
47
+ className
48
+ }) {
49
+ return cn(
50
+ "polli:break-words polli:font-body",
51
+ textSizeClasses[size],
52
+ textToneClasses[tone],
53
+ textWeightClasses[weight],
54
+ className
82
55
  );
83
- return { start, end: addUtcMonths(start, 1) };
84
56
  }
85
- function formatPeriodLabel(selection) {
86
- const { start, end } = periodToWindow(selection);
87
- if (selection.granularity === "day") {
88
- const today = startOfUtcDay();
89
- const yesterday = addUtcDays(today, -1);
90
- if (start.getTime() === today.getTime()) return "Today";
91
- if (start.getTime() === yesterday.getTime()) return "Yesterday";
92
- return start.toLocaleDateString("en-US", {
93
- timeZone: "UTC",
94
- month: "short",
95
- day: "numeric",
96
- year: "numeric"
97
- });
98
- }
99
- if (selection.granularity === "week") {
100
- const weekEnd = addUtcDays(end, -1);
101
- return `${start.toLocaleDateString("en-US", {
102
- timeZone: "UTC",
103
- month: "short",
104
- day: "numeric"
105
- })} - ${weekEnd.toLocaleDateString("en-US", {
106
- timeZone: "UTC",
107
- month: "short",
108
- day: "numeric",
109
- year: "numeric"
110
- })}`;
111
- }
112
- return start.toLocaleDateString("en-US", {
113
- timeZone: "UTC",
114
- month: "long",
115
- year: "numeric"
116
- });
57
+ function Heading({
58
+ as,
59
+ size = "section",
60
+ className,
61
+ children,
62
+ ...rest
63
+ }) {
64
+ const Component = as || "h2";
65
+ return /* @__PURE__ */ jsx(Component, { ...rest, className: headingClassName(size, className), children });
117
66
  }
118
- function getPeriodBucketKeys(selection) {
119
- const { start, end } = periodToWindow(selection);
120
- const bucketKeys = [];
121
- const cursor = new Date(start);
122
- if (selection.granularity === "day") {
123
- while (cursor < end) {
124
- bucketKeys.push(`${formatUtcHourPeriod(cursor)}:00:00`);
125
- cursor.setUTCHours(cursor.getUTCHours() + 1);
67
+ function Text({
68
+ as,
69
+ size = "body",
70
+ tone = "base",
71
+ weight = "normal",
72
+ className,
73
+ children,
74
+ ...rest
75
+ }) {
76
+ const Component = as || "p";
77
+ return /* @__PURE__ */ jsx(
78
+ Component,
79
+ {
80
+ ...rest,
81
+ className: textClassName({ size, tone, weight, className }),
82
+ children
126
83
  }
127
- return bucketKeys;
128
- }
129
- while (cursor < end) {
130
- bucketKeys.push(formatUtcDatePeriod(cursor));
131
- cursor.setUTCDate(cursor.getUTCDate() + 1);
132
- }
133
- return bucketKeys;
134
- }
135
- function periodBucketKeyToDate(bucketKey, granularity) {
136
- if (granularity === "day") {
137
- return /* @__PURE__ */ new Date(`${bucketKey.replace(" ", "T")}.000Z`);
138
- }
139
- return /* @__PURE__ */ new Date(`${bucketKey}T00:00:00.000Z`);
140
- }
141
- function isPeriodSelectable(selection, minDate = /* @__PURE__ */ new Date(0), maxDate = startOfUtcDay()) {
142
- const { start, end } = periodToWindow(selection);
143
- return end > minDate && start <= maxDate;
144
- }
145
-
146
- // src/lib/use-scroll-lock.ts
147
- import { useEffect } from "react";
148
- function useScrollLock(enabled = true) {
149
- useEffect(() => {
150
- if (!enabled) return;
151
- const originalBody = document.body.style.overflow;
152
- const originalHtml = document.documentElement.style.overflow;
153
- document.body.style.overflow = "hidden";
154
- document.documentElement.style.overflow = "hidden";
155
- return () => {
156
- document.body.style.overflow = originalBody;
157
- document.documentElement.style.overflow = originalHtml;
158
- };
159
- }, [enabled]);
160
- }
161
-
162
- // src/lib/cn.ts
163
- import { clsx as clsx2 } from "clsx";
164
- import { extendTailwindMerge } from "tailwind-merge";
165
- var twMerge2 = extendTailwindMerge({ prefix: "polli" });
166
- function cn2(...inputs) {
167
- return twMerge2(clsx2(...inputs));
84
+ );
168
85
  }
169
86
 
170
- // src/primitives/Alert.tsx
171
- import { jsx, jsxs } from "react/jsx-runtime";
87
+ // src/compositions/Alert.tsx
88
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
172
89
  var intentClasses = {
173
- info: "polli:border-theme-border polli:bg-theme-bg-pale polli:text-theme-text-strong",
174
- success: "polli:border-intent-success-border polli:bg-intent-success-bg-light polli:text-intent-success-text",
175
- warning: "polli:border-intent-warning-border polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
176
- danger: "polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
90
+ info: "polli:bg-theme-bg-pale polli:text-theme-text-strong",
91
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
92
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
93
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
177
94
  };
178
95
  var Alert = ({
179
96
  intent = "info",
@@ -186,111 +103,290 @@ var Alert = ({
186
103
  {
187
104
  ...rest,
188
105
  role: intent === "danger" ? "alert" : "status",
189
- className: cn2(
190
- "polli:rounded-xl polli:border polli:px-3 polli:py-2 polli:text-sm",
106
+ className: cn(
107
+ "polli:rounded-xl polli:px-3 polli:py-2 polli:text-sm",
191
108
  intentClasses[intent],
192
109
  className
193
110
  ),
194
111
  children: [
195
- title && /* @__PURE__ */ jsx("div", { className: "polli:mb-1 polli:text-xs polli:font-bold polli:uppercase polli:tracking-wide", children: title }),
196
- /* @__PURE__ */ jsx("div", { children })
112
+ title && /* @__PURE__ */ jsx2(
113
+ Text,
114
+ {
115
+ as: "div",
116
+ size: "xs",
117
+ tone: "strong",
118
+ weight: "bold",
119
+ className: "polli:mb-1 polli:uppercase polli:tracking-wide",
120
+ children: title
121
+ }
122
+ ),
123
+ /* @__PURE__ */ jsx2("div", { children })
197
124
  ]
198
125
  }
199
126
  );
200
127
 
201
- // src/primitives/Button.tsx
202
- import { jsx as jsx2 } from "react/jsx-runtime";
203
- var sizes = {
204
- small: "polli:px-2 polli:pt-0.5 polli:pb-1",
205
- medium: "polli:px-4 polli:pt-1.5 polli:pb-2",
206
- large: "polli:px-6 polli:py-3"
207
- };
208
- var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
209
- var intentClasses2 = {
210
- danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-[oklch(0.88_0.075_25)] polli:transition-colors"
211
- };
212
- var buttonClasses = ({
213
- theme: _theme,
214
- intent,
215
- size,
216
- className,
217
- disabled
218
- }) => {
219
- const colorClasses = intent ? intentClasses2[intent] : themeClasses;
220
- return cn2(
221
- "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",
222
- disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
223
- colorClasses,
224
- sizes[size || "medium"],
225
- className
226
- );
128
+ // src/compositions/AppHeader.tsx
129
+ import { useEffect, useState } from "react";
130
+
131
+ // src/assets/logo-wordmark.svg
132
+ 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>';
133
+
134
+ // src/compositions/AppHeader.tsx
135
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
136
+ var brandWordmarkMaskUrl = `url('${logo_wordmark_default}')`;
137
+ var brandWordmarkMask = {
138
+ WebkitMaskImage: brandWordmarkMaskUrl,
139
+ WebkitMaskPosition: "center",
140
+ WebkitMaskRepeat: "no-repeat",
141
+ WebkitMaskSize: "contain",
142
+ maskImage: brandWordmarkMaskUrl,
143
+ maskPosition: "center",
144
+ maskRepeat: "no-repeat",
145
+ maskSize: "contain"
227
146
  };
228
- function Button({
229
- as,
147
+ function scrollTopFor(target) {
148
+ return target === window ? window.scrollY : target.scrollTop;
149
+ }
150
+ function AppHeader({
230
151
  children,
231
- theme,
232
- intent,
233
- size,
152
+ navLabel,
153
+ autoHide = false,
154
+ scrollTargetRef,
155
+ brandHref = "https://pollinations.ai",
156
+ brandLabel = "Pollinations",
234
157
  className,
235
- disabled,
236
- ...buttonProps
158
+ innerClassName,
159
+ navClassName
237
160
  }) {
238
- const Component = as || "button";
239
- return /* @__PURE__ */ jsx2(
240
- Component,
161
+ const [hidden, setHidden] = useState(false);
162
+ useEffect(() => {
163
+ if (!autoHide || typeof window === "undefined") {
164
+ setHidden(false);
165
+ return;
166
+ }
167
+ const target = scrollTargetRef?.current ?? window;
168
+ let lastScrollTop = scrollTopFor(target);
169
+ let frameId = 0;
170
+ const handleScroll = () => {
171
+ if (frameId) return;
172
+ frameId = window.requestAnimationFrame(() => {
173
+ frameId = 0;
174
+ const nextScrollTop = scrollTopFor(target);
175
+ const delta = nextScrollTop - lastScrollTop;
176
+ if (nextScrollTop < 16) {
177
+ setHidden(false);
178
+ } else if (delta > 8) {
179
+ setHidden(true);
180
+ } else if (delta < -8) {
181
+ setHidden(false);
182
+ }
183
+ lastScrollTop = nextScrollTop;
184
+ });
185
+ };
186
+ target.addEventListener("scroll", handleScroll, { passive: true });
187
+ return () => {
188
+ if (frameId) window.cancelAnimationFrame(frameId);
189
+ target.removeEventListener("scroll", handleScroll);
190
+ };
191
+ }, [autoHide, scrollTargetRef]);
192
+ return /* @__PURE__ */ jsx3(
193
+ "header",
241
194
  {
242
- "data-theme": intent ? void 0 : theme,
243
- className: buttonClasses({
244
- theme,
245
- intent,
246
- size,
247
- className,
248
- disabled
249
- }),
250
- disabled,
251
- ...buttonProps,
252
- children
195
+ className: cn(
196
+ "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",
197
+ "polli:transition-transform polli:duration-200 polli:ease-out",
198
+ autoHide && "polli:will-change-transform",
199
+ hidden ? "polli:-translate-y-full" : "polli:translate-y-0",
200
+ className
201
+ ),
202
+ onFocusCapture: () => setHidden(false),
203
+ children: /* @__PURE__ */ jsxs2(
204
+ "div",
205
+ {
206
+ className: cn(
207
+ "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",
208
+ innerClassName
209
+ ),
210
+ children: [
211
+ /* @__PURE__ */ jsxs2(
212
+ "a",
213
+ {
214
+ href: brandHref,
215
+ target: "_blank",
216
+ rel: "noopener noreferrer",
217
+ className: "polli:inline-flex polli:shrink-0 polli:items-center polli:text-theme-text-strong",
218
+ children: [
219
+ /* @__PURE__ */ jsx3("span", { className: "polli:sr-only", children: brandLabel }),
220
+ /* @__PURE__ */ jsx3(
221
+ "span",
222
+ {
223
+ "aria-hidden": "true",
224
+ className: "polli:block polli:h-7 polli:w-[220px] polli:max-w-full polli:bg-current",
225
+ style: brandWordmarkMask
226
+ }
227
+ )
228
+ ]
229
+ }
230
+ ),
231
+ children ? /* @__PURE__ */ jsx3(
232
+ "nav",
233
+ {
234
+ "aria-label": navLabel,
235
+ className: cn(
236
+ "polli:flex polli:min-w-0 polli:flex-wrap polli:gap-2",
237
+ navClassName
238
+ ),
239
+ children
240
+ }
241
+ ) : null
242
+ ]
243
+ }
244
+ )
253
245
  }
254
246
  );
255
247
  }
256
248
 
257
- // src/primitives/ButtonGroup.tsx
258
- import { jsx as jsx3 } from "react/jsx-runtime";
259
- var ButtonGroup = ({
260
- wrap = true,
261
- className,
262
- children,
263
- role = "group",
264
- ...rest
265
- }) => /* @__PURE__ */ jsx3(
266
- "div",
267
- {
268
- ...rest,
269
- role,
270
- className: cn2(
271
- "polli:flex polli:min-w-0 polli:items-center polli:gap-1.5",
272
- wrap ? "polli:flex-wrap" : "polli:flex-nowrap",
273
- className
274
- ),
275
- children
276
- }
277
- );
278
-
279
- // src/primitives/ChevronIcon.tsx
249
+ // src/primitives/ScrollArea.tsx
250
+ import {
251
+ forwardRef,
252
+ useCallback,
253
+ useEffect as useEffect2,
254
+ useRef
255
+ } from "react";
280
256
  import { jsx as jsx4 } from "react/jsx-runtime";
281
- var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx4(
282
- "svg",
257
+ var axisClasses = {
258
+ y: "polli:overflow-y-auto polli:overflow-x-hidden",
259
+ x: "polli:overflow-x-auto polli:overflow-y-hidden"
260
+ };
261
+ function assignRef(ref, value) {
262
+ if (typeof ref === "function") ref(value);
263
+ else if (ref) ref.current = value;
264
+ }
265
+ var ScrollArea = forwardRef(
266
+ ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
267
+ const innerRef = useRef(null);
268
+ const setRef = useCallback(
269
+ (node) => {
270
+ innerRef.current = node;
271
+ assignRef(externalRef, node);
272
+ },
273
+ [externalRef]
274
+ );
275
+ useEffect2(() => {
276
+ const element = innerRef.current;
277
+ if (!element) return;
278
+ let hideTimer = null;
279
+ const clearHideTimer = () => {
280
+ if (hideTimer !== null) {
281
+ window.clearTimeout(hideTimer);
282
+ hideTimer = null;
283
+ }
284
+ };
285
+ const show = () => {
286
+ element.dataset.scrollbarActive = "true";
287
+ clearHideTimer();
288
+ };
289
+ const hide = () => {
290
+ element.dataset.scrollbarActive = "false";
291
+ clearHideTimer();
292
+ };
293
+ const scheduleHide = () => {
294
+ clearHideTimer();
295
+ hideTimer = window.setTimeout(hide, 2e3);
296
+ };
297
+ const handleInteraction = () => {
298
+ show();
299
+ scheduleHide();
300
+ };
301
+ hide();
302
+ element.addEventListener("scroll", handleInteraction, {
303
+ passive: true
304
+ });
305
+ element.addEventListener("wheel", handleInteraction, {
306
+ passive: true
307
+ });
308
+ element.addEventListener("touchstart", handleInteraction, {
309
+ passive: true
310
+ });
311
+ element.addEventListener("pointerdown", handleInteraction);
312
+ element.addEventListener("keydown", handleInteraction);
313
+ element.addEventListener("focusin", handleInteraction);
314
+ element.addEventListener("focusout", scheduleHide);
315
+ return () => {
316
+ clearHideTimer();
317
+ element.removeEventListener("scroll", handleInteraction);
318
+ element.removeEventListener("wheel", handleInteraction);
319
+ element.removeEventListener("touchstart", handleInteraction);
320
+ element.removeEventListener("pointerdown", handleInteraction);
321
+ element.removeEventListener("keydown", handleInteraction);
322
+ element.removeEventListener("focusin", handleInteraction);
323
+ element.removeEventListener("focusout", scheduleHide);
324
+ };
325
+ }, []);
326
+ return /* @__PURE__ */ jsx4(
327
+ "div",
328
+ {
329
+ ...rest,
330
+ ref: setRef,
331
+ "data-theme": theme,
332
+ className: cn(
333
+ "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
334
+ axisClasses[axis],
335
+ className
336
+ ),
337
+ children
338
+ }
339
+ );
340
+ }
341
+ );
342
+ ScrollArea.displayName = "ScrollArea";
343
+
344
+ // src/compositions/CodeBlock.tsx
345
+ import { jsx as jsx5 } from "react/jsx-runtime";
346
+ var CodeBlock = ({
347
+ code,
348
+ theme,
349
+ codeClassName,
350
+ className,
351
+ ...rest
352
+ }) => /* @__PURE__ */ jsx5(
353
+ ScrollArea,
354
+ {
355
+ ...rest,
356
+ theme,
357
+ axis: "x",
358
+ className: cn(
359
+ "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale",
360
+ className
361
+ ),
362
+ children: /* @__PURE__ */ jsx5(
363
+ "pre",
364
+ {
365
+ className: cn(
366
+ "polli:p-4 polli:font-mono polli:text-xs polli:leading-6 polli:text-theme-text-strong",
367
+ codeClassName
368
+ ),
369
+ children: /* @__PURE__ */ jsx5("code", { children: code })
370
+ }
371
+ )
372
+ }
373
+ );
374
+
375
+ // src/primitives/ChevronIcon.tsx
376
+ import { jsx as jsx6 } from "react/jsx-runtime";
377
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx6(
378
+ "svg",
283
379
  {
284
380
  "aria-hidden": "true",
285
381
  width: "12",
286
382
  height: "12",
287
383
  viewBox: "0 0 12 12",
288
- className: cn2(
384
+ className: cn(
289
385
  "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
290
386
  expanded && "polli:rotate-180",
291
387
  className
292
388
  ),
293
- children: /* @__PURE__ */ jsx4(
389
+ children: /* @__PURE__ */ jsx6(
294
390
  "path",
295
391
  {
296
392
  d: "M3 4.5 6 7.5l3-3",
@@ -304,48 +400,8 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx4(
304
400
  }
305
401
  );
306
402
 
307
- // src/primitives/Chip.tsx
308
- import { jsx as jsx5 } from "react/jsx-runtime";
309
- var chipSizes = {
310
- sm: "polli:px-2 polli:py-0.5 polli:text-xs",
311
- md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
312
- lg: "polli:px-3 polli:py-1 polli:text-sm"
313
- };
314
- var intentClasses3 = {
315
- news: "polli:bg-[oklch(0.935_0.06_158)] polli:text-[oklch(0.46_0.13_158)]",
316
- alpha: "polli:bg-[oklch(0.93_0.06_300)] polli:text-[oklch(0.42_0.18_300)]",
317
- neutral: "polli:border polli:border-gray-400/70 polli:bg-gray-100/80 polli:text-gray-900",
318
- success: "polli:border polli:border-intent-success-border polli:bg-intent-success-bg-light polli:text-intent-success-text",
319
- warning: "polli:border polli:border-intent-warning-border polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
320
- danger: "polli:border polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
321
- };
322
- var Chip = ({
323
- theme,
324
- intent,
325
- size = "md",
326
- className,
327
- children,
328
- ...rest
329
- }) => {
330
- const intentClass = intent ? intentClasses3[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
331
- return /* @__PURE__ */ jsx5(
332
- "span",
333
- {
334
- ...rest,
335
- "data-theme": theme,
336
- className: cn2(
337
- "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
338
- chipSizes[size],
339
- intentClass,
340
- className
341
- ),
342
- children
343
- }
344
- );
345
- };
346
-
347
- // src/primitives/Collapsible.tsx
348
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
403
+ // src/compositions/Collapsible.tsx
404
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
349
405
  var Collapsible = ({
350
406
  label,
351
407
  expanded,
@@ -357,16 +413,16 @@ var Collapsible = ({
357
413
  focusClassName,
358
414
  panelClassName = "polli:border-t polli:border-theme-border polli:px-3 polli:pt-3 polli:pb-3",
359
415
  ariaLabel
360
- }) => /* @__PURE__ */ jsxs2(
416
+ }) => /* @__PURE__ */ jsxs3(
361
417
  "div",
362
418
  {
363
- className: cn2(
419
+ className: cn(
364
420
  "polli:rounded-lg polli:border polli:transition-all",
365
421
  wrapperClassName,
366
422
  disabled && "polli:opacity-50"
367
423
  ),
368
424
  children: [
369
- /* @__PURE__ */ jsxs2(
425
+ /* @__PURE__ */ jsxs3(
370
426
  "button",
371
427
  {
372
428
  type: "button",
@@ -374,16 +430,16 @@ var Collapsible = ({
374
430
  "aria-label": ariaLabel,
375
431
  disabled,
376
432
  onClick: onToggle,
377
- className: cn2(
378
- "polli:w-full polli:flex polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:transition-colors",
433
+ className: cn(
434
+ "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",
379
435
  expanded ? "polli:rounded-t-lg" : "polli:rounded-lg",
380
436
  !disabled && hoverClassName,
381
437
  focusClassName,
382
438
  disabled ? "polli:cursor-not-allowed" : "polli:cursor-pointer"
383
439
  ),
384
440
  children: [
385
- /* @__PURE__ */ jsx6("div", { className: "polli:flex-1 polli:min-w-0", children: label }),
386
- /* @__PURE__ */ jsx6(
441
+ /* @__PURE__ */ jsx7("div", { className: "polli:flex-1 polli:min-w-0", children: label }),
442
+ /* @__PURE__ */ jsx7(
387
443
  ChevronIcon,
388
444
  {
389
445
  expanded,
@@ -393,24 +449,24 @@ var Collapsible = ({
393
449
  ]
394
450
  }
395
451
  ),
396
- expanded && /* @__PURE__ */ jsx6("div", { className: panelClassName, children })
452
+ expanded && /* @__PURE__ */ jsx7("div", { className: panelClassName, children })
397
453
  ]
398
454
  }
399
455
  );
400
456
 
401
- // src/primitives/CopyButton.tsx
457
+ // src/compositions/CopyButton.tsx
402
458
  import {
403
- useEffect as useEffect2,
404
- useRef as useRef2,
405
- useState as useState2
459
+ useEffect as useEffect3,
460
+ useRef as useRef3,
461
+ useState as useState3
406
462
  } from "react";
407
463
 
408
464
  // src/primitives/Tooltip.tsx
409
465
  import {
410
- useRef,
411
- useState
466
+ useRef as useRef2,
467
+ useState as useState2
412
468
  } from "react";
413
- import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
469
+ import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
414
470
  var TOOLTIP_MAX_WIDTH = 288;
415
471
  var TOOLTIP_VIEWPORT_MARGIN = 12;
416
472
  var Tooltip = ({
@@ -423,13 +479,13 @@ var Tooltip = ({
423
479
  triggerAs = "button",
424
480
  displayContents = false
425
481
  }) => {
426
- const [showTooltip, setShowTooltip] = useState(false);
427
- const [tooltipPosition, setTooltipPosition] = useState({
482
+ const [showTooltip, setShowTooltip] = useState2(false);
483
+ const [tooltipPosition, setTooltipPosition] = useState2({
428
484
  top: 0,
429
485
  left: 0,
430
486
  maxWidth: TOOLTIP_MAX_WIDTH
431
487
  });
432
- const triggerRef = useRef(null);
488
+ const triggerRef = useRef2(null);
433
489
  const updateTooltipPosition = () => {
434
490
  if (triggerRef.current) {
435
491
  const rect = triggerRef.current.getBoundingClientRect();
@@ -451,15 +507,15 @@ var Tooltip = ({
451
507
  });
452
508
  }
453
509
  };
454
- const triggerClassName = cn2(
455
- "polli:relative polli:cursor-help polli:text-left polli:inline-flex polli:items-center",
510
+ const triggerClassName = cn(
511
+ "polli-control polli:relative polli:cursor-help polli:text-left polli:inline-flex polli:items-center",
456
512
  className
457
513
  );
458
514
  const cursorClass = displayContents ? "polli:contents" : "polli:cursor-help";
459
515
  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";
460
- const contentNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
461
- /* @__PURE__ */ jsx7("span", { className: cursorClass, children }),
462
- /* @__PURE__ */ jsx7(
516
+ const contentNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
517
+ /* @__PURE__ */ jsx8("span", { className: cursorClass, children }),
518
+ /* @__PURE__ */ jsx8(
463
519
  "span",
464
520
  {
465
521
  style: {
@@ -494,7 +550,7 @@ var Tooltip = ({
494
550
  style
495
551
  };
496
552
  if (triggerAs === "span") {
497
- return /* @__PURE__ */ jsx7(
553
+ return /* @__PURE__ */ jsx8(
498
554
  "span",
499
555
  {
500
556
  ref: (node) => {
@@ -505,7 +561,7 @@ var Tooltip = ({
505
561
  }
506
562
  );
507
563
  }
508
- return /* @__PURE__ */ jsx7(
564
+ return /* @__PURE__ */ jsx8(
509
565
  "button",
510
566
  {
511
567
  ref: (node) => {
@@ -523,8 +579,8 @@ var Tooltip = ({
523
579
  );
524
580
  };
525
581
 
526
- // src/primitives/CopyButton.tsx
527
- import { jsx as jsx8 } from "react/jsx-runtime";
582
+ // src/compositions/CopyButton.tsx
583
+ import { jsx as jsx9 } from "react/jsx-runtime";
528
584
  function CopyButton({
529
585
  value,
530
586
  children,
@@ -537,9 +593,9 @@ function CopyButton({
537
593
  onCopyError,
538
594
  ...buttonProps
539
595
  }) {
540
- const [copied, setCopied] = useState2(false);
541
- const timeoutRef = useRef2(null);
542
- useEffect2(
596
+ const [copied, setCopied] = useState3(false);
597
+ const timeoutRef = useRef3(null);
598
+ useEffect3(
543
599
  () => () => {
544
600
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
545
601
  },
@@ -561,19 +617,20 @@ function CopyButton({
561
617
  onCopyError?.(error);
562
618
  }
563
619
  }
564
- const button = /* @__PURE__ */ jsx8(
620
+ const button = /* @__PURE__ */ jsx9(
565
621
  "button",
566
622
  {
567
623
  ...buttonProps,
568
624
  type: "button",
569
625
  onClick: handleCopy,
570
- className: cn2(
626
+ className: cn(
627
+ "polli-control",
571
628
  typeof className === "function" ? className(copied) : className
572
629
  ),
573
630
  children: typeof children === "function" ? children(copied) : children
574
631
  }
575
632
  );
576
- return /* @__PURE__ */ jsx8(
633
+ return /* @__PURE__ */ jsx9(
577
634
  Tooltip,
578
635
  {
579
636
  triggerAs: "span",
@@ -584,171 +641,87 @@ function CopyButton({
584
641
  );
585
642
  }
586
643
 
587
- // src/primitives/Dialog.tsx
588
- import { Dialog as ArkDialog } from "@ark-ui/react/dialog";
589
- import { Portal } from "@ark-ui/react/portal";
590
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
591
- var sizeClasses = {
592
- sm: "polli:max-w-md",
593
- md: "polli:max-w-xl",
594
- lg: "polli:max-w-2xl"
644
+ // src/primitives/Button.tsx
645
+ import { jsx as jsx10 } from "react/jsx-runtime";
646
+ var sizes = {
647
+ sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
648
+ md: "polli:px-4 polli:pt-1.5 polli:pb-2",
649
+ lg: "polli:px-6 polli:py-3"
595
650
  };
596
- var Dialog = ({
597
- open,
598
- onOpenChange,
599
- trigger,
600
- triggerAsChild = false,
601
- triggerClassName,
602
- title,
603
- titleClassName,
604
- ariaLabel,
605
- labelledBy,
606
- theme = "blue",
607
- size = "md",
608
- showBackdrop = true,
609
- backdropClassName,
610
- positionerClassName,
611
- contentClassName,
612
- children
613
- }) => /* @__PURE__ */ jsxs4(
614
- ArkDialog.Root,
615
- {
616
- open,
617
- onOpenChange: (details) => onOpenChange?.(details.open),
618
- children: [
619
- trigger && /* @__PURE__ */ jsx9(
620
- ArkDialog.Trigger,
621
- {
622
- asChild: triggerAsChild,
623
- className: triggerClassName,
624
- children: trigger
625
- }
626
- ),
627
- /* @__PURE__ */ jsxs4(Portal, { children: [
628
- showBackdrop && /* @__PURE__ */ jsx9(
629
- ArkDialog.Backdrop,
630
- {
631
- className: cn2(
632
- "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
633
- backdropClassName
634
- )
635
- }
636
- ),
637
- /* @__PURE__ */ jsx9(
638
- ArkDialog.Positioner,
639
- {
640
- className: cn2(
641
- "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",
642
- positionerClassName
643
- ),
644
- children: /* @__PURE__ */ jsxs4(
645
- ArkDialog.Content,
646
- {
647
- "data-theme": theme,
648
- "aria-label": ariaLabel,
649
- "aria-labelledby": labelledBy,
650
- className: cn2(
651
- "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",
652
- sizeClasses[size],
653
- contentClassName
654
- ),
655
- children: [
656
- title && /* @__PURE__ */ jsx9(
657
- DialogTitle,
658
- {
659
- className: cn2(
660
- "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
661
- titleClassName
662
- ),
663
- children: title
664
- }
665
- ),
666
- children
667
- ]
668
- }
669
- )
670
- }
671
- )
672
- ] })
673
- ]
674
- }
675
- );
676
- var DialogTitle = ArkDialog.Title;
677
-
678
- // src/primitives/Dropdown.tsx
679
- import { Popover } from "@ark-ui/react/popover";
680
- import { Portal as Portal2 } from "@ark-ui/react/portal";
681
- import { useState as useState3 } from "react";
682
- import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
683
- var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-surface-white polli:shadow-lg";
684
- var Dropdown = ({
685
- theme,
686
- trigger,
687
- children,
688
- align = "start",
689
- open: openProp,
690
- onOpenChange,
691
- panelClassName,
692
- className
651
+ var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
652
+ var intentClasses2 = {
653
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:transition-colors"
654
+ };
655
+ var buttonClasses = ({
656
+ theme: _theme,
657
+ intent,
658
+ size,
659
+ className,
660
+ disabled
693
661
  }) => {
694
- const [internalOpen, setInternalOpen] = useState3(false);
695
- const isControlled = openProp !== void 0;
696
- const open = isControlled ? openProp : internalOpen;
697
- const setOpen = (next) => {
698
- if (!isControlled) setInternalOpen(next);
699
- onOpenChange?.(next);
700
- };
701
- return /* @__PURE__ */ jsxs5(
702
- Popover.Root,
703
- {
704
- open,
705
- onOpenChange: (details) => setOpen(details.open),
706
- positioning: {
707
- placement: align === "end" ? "bottom-end" : "bottom-start"
708
- },
709
- children: [
710
- /* @__PURE__ */ jsx10(Popover.Trigger, { asChild: true, children: trigger(open) }),
711
- /* @__PURE__ */ jsx10(Portal2, { children: /* @__PURE__ */ jsx10(Popover.Positioner, { children: /* @__PURE__ */ jsx10(
712
- Popover.Content,
713
- {
714
- "data-theme": theme,
715
- className: cn2(
716
- "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
717
- panelClassName ?? DEFAULT_PANEL,
718
- className
719
- ),
720
- children: typeof children === "function" ? children(() => setOpen(false)) : children
721
- }
722
- ) }) })
723
- ]
724
- }
662
+ const colorClasses = intent ? intentClasses2[intent] : themeClasses;
663
+ return cn(
664
+ "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",
665
+ disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
666
+ colorClasses,
667
+ sizes[size || "md"],
668
+ className
725
669
  );
726
670
  };
727
-
728
- // src/primitives/icons/index.tsx
729
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
730
- var strokeProps = {
731
- fill: "none",
732
- stroke: "currentColor",
733
- strokeWidth: 2,
734
- strokeLinecap: "round",
735
- strokeLinejoin: "round"
736
- };
737
- function AppIcon(props) {
738
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
739
- /* @__PURE__ */ jsx11("rect", { x: "2", y: "4", width: "20", height: "14", rx: "2" }),
671
+ function Button({
672
+ as,
673
+ children,
674
+ theme,
675
+ intent,
676
+ size,
677
+ className,
678
+ disabled,
679
+ ...buttonProps
680
+ }) {
681
+ const Component = as || "button";
682
+ return /* @__PURE__ */ jsx10(
683
+ Component,
684
+ {
685
+ "data-theme": intent ? void 0 : theme,
686
+ "data-intent": intent,
687
+ className: buttonClasses({
688
+ theme,
689
+ intent,
690
+ size,
691
+ className,
692
+ disabled
693
+ }),
694
+ disabled,
695
+ ...buttonProps,
696
+ children
697
+ }
698
+ );
699
+ }
700
+
701
+ // src/primitives/icons/index.tsx
702
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
703
+ var strokeProps = {
704
+ fill: "none",
705
+ stroke: "currentColor",
706
+ strokeWidth: 2,
707
+ strokeLinecap: "round",
708
+ strokeLinejoin: "round"
709
+ };
710
+ function AppIcon(props) {
711
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
712
+ /* @__PURE__ */ jsx11("rect", { x: "2", y: "4", width: "20", height: "14", rx: "2" }),
740
713
  /* @__PURE__ */ jsx11("path", { d: "M2 20h20" })
741
714
  ] });
742
715
  }
743
716
  function BeakerIcon(props) {
744
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
717
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
745
718
  /* @__PURE__ */ jsx11("path", { d: "M9 3h6" }),
746
719
  /* @__PURE__ */ jsx11("path", { d: "M10 3v6.5L4.5 18a2 2 0 0 0 1.7 3h11.6a2 2 0 0 0 1.7-3L14 9.5V3" }),
747
720
  /* @__PURE__ */ jsx11("path", { d: "M7 14h10" })
748
721
  ] });
749
722
  }
750
723
  function BookIcon(props) {
751
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
724
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
752
725
  /* @__PURE__ */ jsx11("path", { d: "M4 4h5a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H4z" }),
753
726
  /* @__PURE__ */ jsx11("path", { d: "M20 4h-5a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h6z" })
754
727
  ] });
@@ -767,13 +740,13 @@ function CheckIcon(props) {
767
740
  );
768
741
  }
769
742
  function ClipboardIcon(props) {
770
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
743
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
771
744
  /* @__PURE__ */ jsx11("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
772
745
  /* @__PURE__ */ jsx11("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
773
746
  ] });
774
747
  }
775
748
  function ClockIcon(props) {
776
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
749
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
777
750
  /* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "9" }),
778
751
  /* @__PURE__ */ jsx11("path", { d: "M12 7v5l3 2" })
779
752
  ] });
@@ -788,7 +761,7 @@ function DiscordIcon(props) {
788
761
  ) });
789
762
  }
790
763
  function DownloadIcon(props) {
791
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
764
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
792
765
  /* @__PURE__ */ jsx11("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
793
766
  /* @__PURE__ */ jsx11("polyline", { points: "7 10 12 15 17 10" }),
794
767
  /* @__PURE__ */ jsx11("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
@@ -798,7 +771,7 @@ function ExternalLinkIcon(props) {
798
771
  return /* @__PURE__ */ jsx11("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ jsx11("path", { d: "M7 17 17 7M9 7h8v8" }) });
799
772
  }
800
773
  function GenApiIcon(props) {
801
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
774
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
802
775
  /* @__PURE__ */ jsx11("path", { d: "m8 3 4 1.5L16 3v18l-4-1.5L8 21z" }),
803
776
  /* @__PURE__ */ jsx11("path", { d: "M8 3v18M16 3v18" })
804
777
  ] });
@@ -813,26 +786,33 @@ function GitHubIcon(props) {
813
786
  ) });
814
787
  }
815
788
  function ImageIcon(props) {
816
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
789
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
817
790
  /* @__PURE__ */ jsx11("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
818
791
  /* @__PURE__ */ jsx11("circle", { cx: "9", cy: "9", r: "2" }),
819
792
  /* @__PURE__ */ jsx11("path", { d: "m21 15-5-5L5 21" })
820
793
  ] });
821
794
  }
795
+ function AudioIcon(props) {
796
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
797
+ /* @__PURE__ */ jsx11("path", { d: "M9 18V5l12-2v13" }),
798
+ /* @__PURE__ */ jsx11("circle", { cx: "6", cy: "18", r: "3" }),
799
+ /* @__PURE__ */ jsx11("circle", { cx: "18", cy: "16", r: "3" })
800
+ ] });
801
+ }
822
802
  function LockIcon(props) {
823
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
803
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
824
804
  /* @__PURE__ */ jsx11("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
825
805
  /* @__PURE__ */ jsx11("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
826
806
  ] });
827
807
  }
828
808
  function MailIcon(props) {
829
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
809
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
830
810
  /* @__PURE__ */ jsx11("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
831
811
  /* @__PURE__ */ jsx11("path", { d: "m3 7 9 7 9-7" })
832
812
  ] });
833
813
  }
834
814
  function McpIcon(props) {
835
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
815
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
836
816
  /* @__PURE__ */ jsx11("rect", { x: "2", y: "7", width: "8", height: "10", rx: "1.5" }),
837
817
  /* @__PURE__ */ jsx11("rect", { x: "14", y: "7", width: "8", height: "10", rx: "1.5" }),
838
818
  /* @__PURE__ */ jsx11("path", { d: "M10 12h4" })
@@ -841,8 +821,11 @@ function McpIcon(props) {
841
821
  function MenuIcon(props) {
842
822
  return /* @__PURE__ */ jsx11("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ jsx11("path", { d: "M4 7h16M4 12h16M4 17h16" }) });
843
823
  }
824
+ function PlusIcon(props) {
825
+ return /* @__PURE__ */ jsx11("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ jsx11("path", { d: "M12 5v14M5 12h14" }) });
826
+ }
844
827
  function TerminalIcon(props) {
845
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
828
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
846
829
  /* @__PURE__ */ jsx11("polyline", { points: "4 8 8 12 4 16" }),
847
830
  /* @__PURE__ */ jsx11("line", { x1: "12", y1: "20", x2: "20", y2: "20" })
848
831
  ] });
@@ -851,13 +834,13 @@ function TokensIcon(props) {
851
834
  return /* @__PURE__ */ jsx11("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ jsx11("path", { d: "M4 9h16M4 15h16M10 3 8 21M16 3l-2 18" }) });
852
835
  }
853
836
  function TrendUpIcon(props) {
854
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
837
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
855
838
  /* @__PURE__ */ jsx11("polyline", { points: "3 17 9 11 13 15 21 7" }),
856
839
  /* @__PURE__ */ jsx11("polyline", { points: "15 7 21 7 21 13" })
857
840
  ] });
858
841
  }
859
842
  function WalletIcon(props) {
860
- return /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
843
+ return /* @__PURE__ */ jsxs5("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
861
844
  /* @__PURE__ */ jsx11("path", { d: "M3 7a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v2H5a2 2 0 0 0-2 2V7Z" }),
862
845
  /* @__PURE__ */ jsx11("path", { d: "M3 11a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6Z" }),
863
846
  /* @__PURE__ */ jsx11("circle", { cx: "17", cy: "14", r: "1.25", fill: "currentColor" })
@@ -867,15 +850,15 @@ function XIcon(props) {
867
850
  return /* @__PURE__ */ jsx11("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ jsx11("path", { d: "M18 6 6 18M6 6l12 12" }) });
868
851
  }
869
852
 
870
- // src/primitives/ExternalLinkButton.tsx
871
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
853
+ // src/compositions/ExternalLinkButton.tsx
854
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
872
855
  var ExternalLinkButton = ({
873
856
  theme,
874
857
  href,
875
- size = "medium",
858
+ size = "md",
876
859
  className,
877
860
  children
878
- }) => /* @__PURE__ */ jsxs7(
861
+ }) => /* @__PURE__ */ jsxs6(
879
862
  Button,
880
863
  {
881
864
  as: "a",
@@ -884,7 +867,7 @@ var ExternalLinkButton = ({
884
867
  rel: "noopener noreferrer",
885
868
  theme,
886
869
  size,
887
- className: cn2("polli:gap-2", className),
870
+ className: cn("polli:gap-2", className),
888
871
  children: [
889
872
  /* @__PURE__ */ jsx12("span", { children }),
890
873
  /* @__PURE__ */ jsx12(
@@ -898,13 +881,53 @@ var ExternalLinkButton = ({
898
881
  }
899
882
  );
900
883
 
901
- // src/primitives/Field.tsx
902
- import { Field } from "@ark-ui/react/field";
884
+ // src/compositions/FileUpload.tsx
885
+ import {
886
+ useEffect as useEffect4,
887
+ useId,
888
+ useRef as useRef4,
889
+ useState as useState4
890
+ } from "react";
891
+
892
+ // src/lib/partition-files.ts
893
+ function matchesAccept(file, accept) {
894
+ if (!accept) return true;
895
+ const tokens = accept.split(",").map((t) => t.trim()).filter(Boolean);
896
+ if (tokens.length === 0) return true;
897
+ return tokens.some((token) => {
898
+ if (token.startsWith(".")) {
899
+ return file.name.toLowerCase().endsWith(token.toLowerCase());
900
+ }
901
+ if (token.endsWith("/*")) {
902
+ const prefix = token.slice(0, token.length - 1);
903
+ return file.type.startsWith(prefix);
904
+ }
905
+ return file.type === token;
906
+ });
907
+ }
908
+ function partitionFiles(incoming, current, { maxFiles, maxSizeBytes, accept }) {
909
+ const accepted = [];
910
+ const rejected = [];
911
+ let slots = Math.max(0, maxFiles - current.length);
912
+ for (const file of incoming) {
913
+ if (!matchesAccept(file, accept)) {
914
+ rejected.push({ file, reason: "type" });
915
+ } else if (file.size > maxSizeBytes) {
916
+ rejected.push({ file, reason: "size" });
917
+ } else if (slots <= 0) {
918
+ rejected.push({ file, reason: "count" });
919
+ } else {
920
+ accepted.push(file);
921
+ slots -= 1;
922
+ }
923
+ }
924
+ return { accepted, rejected };
925
+ }
903
926
 
904
927
  // src/primitives/IconButton.tsx
905
928
  import { jsx as jsx13 } from "react/jsx-runtime";
906
- var intentClasses4 = {
907
- danger: "polli:bg-intent-danger-bg-light polli:hover:bg-[oklch(0.88_0.075_25)] polli:text-intent-danger-text"
929
+ var intentClasses3 = {
930
+ danger: "polli:bg-intent-danger-bg-light polli:hover:bg-intent-danger-bg-hover polli:text-intent-danger-text"
908
931
  };
909
932
  var defaultClasses = "polli:bg-theme-bg-active polli:hover:bg-theme-bg-hover polli:text-theme-text-soft polli:hover:text-theme-text-strong";
910
933
  var IconButton = ({
@@ -920,142 +943,535 @@ var IconButton = ({
920
943
  onClick,
921
944
  title,
922
945
  "aria-label": title,
923
- className: cn2(
924
- "polli:inline-flex polli:h-6 polli:w-6 polli:cursor-pointer polli:items-center polli:justify-center polli:rounded polli:transition-colors",
925
- intent ? intentClasses4[intent] : defaultClasses,
946
+ "data-intent": intent,
947
+ className: cn(
948
+ "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",
949
+ intent ? intentClasses3[intent] : defaultClasses,
926
950
  className
927
951
  ),
928
952
  children
929
953
  }
930
954
  );
931
955
 
932
- // src/primitives/InfoTip.tsx
933
- import { jsx as jsx14 } from "react/jsx-runtime";
956
+ // src/compositions/FileUpload.tsx
957
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
958
+ var PREVIEWABLE_IMAGE_TYPES = /* @__PURE__ */ new Set([
959
+ "image/gif",
960
+ "image/jpeg",
961
+ "image/png",
962
+ "image/webp"
963
+ ]);
964
+ var PREVIEW_SIZE = 64;
965
+ var LARGE_PREVIEW_SIZE = 112;
966
+ var previewSizeClasses = {
967
+ sm: "polli:h-16 polli:w-16",
968
+ lg: "polli:h-28 polli:w-28"
969
+ };
970
+ function isPreviewableImage(file) {
971
+ return PREVIEWABLE_IMAGE_TYPES.has(file.type);
972
+ }
973
+ function formatFileSize(bytes) {
974
+ if (bytes < 1024) return `${bytes} B`;
975
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
976
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
977
+ }
978
+ function PreviewPlaceholder({
979
+ icon,
980
+ size
981
+ }) {
982
+ return /* @__PURE__ */ jsx14(
983
+ "div",
984
+ {
985
+ className: cn(
986
+ "polli:flex polli:items-center polli:justify-center polli:rounded-lg polli:bg-theme-bg-active polli:text-theme-text-soft",
987
+ previewSizeClasses[size]
988
+ ),
989
+ children: icon
990
+ }
991
+ );
992
+ }
993
+ function FilePreview({
994
+ file,
995
+ placeholderIcon,
996
+ size = "sm"
997
+ }) {
998
+ const canvasRef = useRef4(null);
999
+ const [canPreview, setCanPreview] = useState4(
1000
+ () => isPreviewableImage(file)
1001
+ );
1002
+ const previewSize = size === "lg" ? LARGE_PREVIEW_SIZE : PREVIEW_SIZE;
1003
+ useEffect4(() => {
1004
+ if (!isPreviewableImage(file)) {
1005
+ setCanPreview(false);
1006
+ return;
1007
+ }
1008
+ let cancelled = false;
1009
+ setCanPreview(true);
1010
+ async function drawPreview() {
1011
+ try {
1012
+ const bitmap = await createImageBitmap(file);
1013
+ if (cancelled) {
1014
+ bitmap.close();
1015
+ return;
1016
+ }
1017
+ const canvas = canvasRef.current;
1018
+ const context = canvas?.getContext("2d");
1019
+ if (!canvas || !context) {
1020
+ bitmap.close();
1021
+ setCanPreview(false);
1022
+ return;
1023
+ }
1024
+ canvas.width = previewSize;
1025
+ canvas.height = previewSize;
1026
+ const scale = Math.max(
1027
+ previewSize / bitmap.width,
1028
+ previewSize / bitmap.height
1029
+ );
1030
+ const width = bitmap.width * scale;
1031
+ const height = bitmap.height * scale;
1032
+ const x = (previewSize - width) / 2;
1033
+ const y = (previewSize - height) / 2;
1034
+ context.clearRect(0, 0, previewSize, previewSize);
1035
+ context.drawImage(bitmap, x, y, width, height);
1036
+ bitmap.close();
1037
+ } catch {
1038
+ if (!cancelled) setCanPreview(false);
1039
+ }
1040
+ }
1041
+ void drawPreview();
1042
+ return () => {
1043
+ cancelled = true;
1044
+ };
1045
+ }, [file, previewSize]);
1046
+ if (!canPreview) {
1047
+ return /* @__PURE__ */ jsx14(PreviewPlaceholder, { icon: placeholderIcon, size });
1048
+ }
1049
+ return /* @__PURE__ */ jsx14(
1050
+ "canvas",
1051
+ {
1052
+ ref: canvasRef,
1053
+ role: "img",
1054
+ "aria-label": file.name,
1055
+ className: cn("polli:rounded-lg", previewSizeClasses[size]),
1056
+ width: previewSize,
1057
+ height: previewSize
1058
+ }
1059
+ );
1060
+ }
1061
+ function FileUpload({
1062
+ value,
1063
+ onChange,
1064
+ onReject,
1065
+ maxFiles = 4,
1066
+ maxSizeBytes = 10 * 1024 * 1024,
1067
+ accept = "image/*",
1068
+ icon = /* @__PURE__ */ jsx14(ImageIcon, { className: "polli:h-6 polli:w-6" }),
1069
+ label = /* @__PURE__ */ jsxs7(Fragment2, { children: [
1070
+ "Drag images here or ",
1071
+ /* @__PURE__ */ jsx14("span", { className: "polli:underline", children: "browse" })
1072
+ ] }),
1073
+ previewIcon = /* @__PURE__ */ jsx14(ImageIcon, { className: "polli:h-5 polli:w-5" }),
1074
+ disabled = false,
1075
+ theme,
1076
+ className
1077
+ }) {
1078
+ useEffect4(() => {
1079
+ const prevent = (event) => event.preventDefault();
1080
+ document.addEventListener("dragover", prevent);
1081
+ document.addEventListener("drop", prevent);
1082
+ return () => {
1083
+ document.removeEventListener("dragover", prevent);
1084
+ document.removeEventListener("drop", prevent);
1085
+ };
1086
+ }, []);
1087
+ function addFiles(incoming) {
1088
+ if (disabled || incoming.length === 0) return;
1089
+ const { accepted, rejected } = partitionFiles(incoming, value, {
1090
+ maxFiles,
1091
+ maxSizeBytes,
1092
+ accept
1093
+ });
1094
+ if (accepted.length > 0) onChange([...value, ...accepted]);
1095
+ if (rejected.length > 0) onReject?.(rejected);
1096
+ }
1097
+ const hasFiles = value.length > 0;
1098
+ const canAdd = !disabled && value.length < maxFiles;
1099
+ const isSingleFile = maxFiles === 1;
1100
+ const previewSize = isSingleFile ? "lg" : "sm";
1101
+ const inputId = useId();
1102
+ const addInputId = `${inputId}-add`;
1103
+ function handleInputChange(event) {
1104
+ addFiles(Array.from(event.target.files ?? []));
1105
+ event.target.value = "";
1106
+ }
1107
+ return /* @__PURE__ */ jsx14(
1108
+ "div",
1109
+ {
1110
+ "data-theme": theme,
1111
+ className: cn("polli:flex polli:flex-col polli:gap-2", className),
1112
+ children: /* @__PURE__ */ jsx14(
1113
+ "fieldset",
1114
+ {
1115
+ disabled,
1116
+ className: cn(
1117
+ "polli:m-0",
1118
+ "polli:rounded-xl polli:border polli:border-dashed polli:border-theme-border polli:bg-theme-bg-pale",
1119
+ "polli:px-4 polli:py-4 polli:text-center polli:text-sm",
1120
+ "polli:text-theme-text-soft polli:transition-colors",
1121
+ disabled ? "polli:opacity-50" : "polli:hover:bg-theme-bg-hover"
1122
+ ),
1123
+ onDragOver: (e) => e.preventDefault(),
1124
+ onDrop: (e) => {
1125
+ e.preventDefault();
1126
+ if (disabled) return;
1127
+ addFiles(Array.from(e.dataTransfer.files));
1128
+ },
1129
+ children: !hasFiles ? /* @__PURE__ */ jsxs7(
1130
+ "label",
1131
+ {
1132
+ htmlFor: inputId,
1133
+ className: cn(
1134
+ "polli-control polli:flex polli:min-h-32 polli:flex-col polli:items-center polli:justify-center polli:gap-2 polli:rounded-lg",
1135
+ canAdd ? "polli:cursor-pointer" : "polli:cursor-not-allowed"
1136
+ ),
1137
+ children: [
1138
+ icon,
1139
+ /* @__PURE__ */ jsx14("span", { children: label }),
1140
+ /* @__PURE__ */ jsx14(
1141
+ "input",
1142
+ {
1143
+ id: inputId,
1144
+ type: "file",
1145
+ accept,
1146
+ multiple: maxFiles > 1,
1147
+ disabled: disabled || !canAdd,
1148
+ className: "polli:sr-only",
1149
+ onChange: handleInputChange
1150
+ }
1151
+ )
1152
+ ]
1153
+ }
1154
+ ) : /* @__PURE__ */ jsxs7("div", { className: "polli:flex polli:flex-col polli:gap-3", children: [
1155
+ /* @__PURE__ */ jsxs7(
1156
+ "ul",
1157
+ {
1158
+ className: cn(
1159
+ "polli:m-0 polli:grid polli:grid-cols-[repeat(auto-fill,minmax(5rem,1fr))] polli:gap-3 polli:p-0",
1160
+ isSingleFile && "polli:flex polli:justify-center"
1161
+ ),
1162
+ children: [
1163
+ value.map((file, index) => /* @__PURE__ */ jsxs7(
1164
+ "li",
1165
+ {
1166
+ className: cn(
1167
+ "polli:relative polli:flex polli:min-w-0 polli:list-none polli:flex-col polli:items-center polli:gap-1",
1168
+ isSingleFile && "polli:max-w-full"
1169
+ ),
1170
+ children: [
1171
+ /* @__PURE__ */ jsx14(
1172
+ FilePreview,
1173
+ {
1174
+ file,
1175
+ placeholderIcon: previewIcon,
1176
+ size: previewSize
1177
+ }
1178
+ ),
1179
+ /* @__PURE__ */ jsx14(
1180
+ "span",
1181
+ {
1182
+ className: cn(
1183
+ "polli:max-w-full polli:truncate polli:text-xs polli:font-medium polli:text-theme-text-base",
1184
+ isSingleFile ? "polli:w-36" : "polli:w-16"
1185
+ ),
1186
+ children: file.name
1187
+ }
1188
+ ),
1189
+ /* @__PURE__ */ jsx14("span", { className: "polli:text-micro polli:text-theme-text-muted", children: formatFileSize(file.size) }),
1190
+ !disabled && /* @__PURE__ */ jsx14("div", { className: "polli:absolute polli:-top-2 polli:right-1", children: /* @__PURE__ */ jsx14(
1191
+ IconButton,
1192
+ {
1193
+ intent: "danger",
1194
+ title: `Remove ${file.name}`,
1195
+ onClick: () => onChange(
1196
+ value.filter(
1197
+ (_, i) => i !== index
1198
+ )
1199
+ ),
1200
+ children: /* @__PURE__ */ jsx14(XIcon, { className: "polli:h-3 polli:w-3" })
1201
+ }
1202
+ ) })
1203
+ ]
1204
+ },
1205
+ `${file.name}-${index}`
1206
+ )),
1207
+ !isSingleFile && canAdd && /* @__PURE__ */ jsx14("li", { className: "polli:flex polli:list-none", children: /* @__PURE__ */ jsxs7(
1208
+ "label",
1209
+ {
1210
+ htmlFor: addInputId,
1211
+ 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",
1212
+ children: [
1213
+ /* @__PURE__ */ jsx14(PlusIcon, { className: "polli:h-5 polli:w-5" }),
1214
+ /* @__PURE__ */ jsx14("span", { className: "polli:text-xs polli:font-medium", children: "Add" }),
1215
+ /* @__PURE__ */ jsx14(
1216
+ "input",
1217
+ {
1218
+ id: addInputId,
1219
+ type: "file",
1220
+ accept,
1221
+ multiple: true,
1222
+ disabled: disabled || !canAdd,
1223
+ className: "polli:sr-only",
1224
+ onChange: handleInputChange
1225
+ }
1226
+ )
1227
+ ]
1228
+ }
1229
+ ) })
1230
+ ]
1231
+ }
1232
+ ),
1233
+ maxFiles > 1 && /* @__PURE__ */ jsxs7("span", { className: "polli:text-xs polli:text-theme-text-muted", children: [
1234
+ value.length,
1235
+ " / ",
1236
+ maxFiles,
1237
+ " files"
1238
+ ] })
1239
+ ] })
1240
+ }
1241
+ )
1242
+ }
1243
+ );
1244
+ }
1245
+
1246
+ // src/compositions/InfoTip.tsx
1247
+ import { jsx as jsx15 } from "react/jsx-runtime";
934
1248
  var InfoTip = ({
935
1249
  text,
936
1250
  content,
937
1251
  label = "More info"
938
- }) => /* @__PURE__ */ jsx14(Tooltip, { content: content ?? text, ariaLabel: label, className: "polli:ml-1", children: /* @__PURE__ */ jsx14("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" }) });
1252
+ }) => /* @__PURE__ */ jsx15(Tooltip, { content: content ?? text, ariaLabel: label, className: "polli:ml-1", children: /* @__PURE__ */ jsx15("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" }) });
939
1253
 
940
- // src/primitives/Input.tsx
941
- import { forwardRef } from "react";
942
- import { jsx as jsx15 } from "react/jsx-runtime";
943
- var Input = forwardRef(
944
- ({ className, error, hideNumberSteppers, ...props }, ref) => /* @__PURE__ */ jsx15(
945
- "input",
1254
+ // src/primitives/Surface.tsx
1255
+ import { jsx as jsx16 } from "react/jsx-runtime";
1256
+ var variantClasses = {
1257
+ panel: "polli:rounded-2xl polli:border polli:border-theme-border polli:bg-theme-bg-subtle polli:p-6",
1258
+ card: "polli:rounded-xl polli:bg-surface-white polli:p-4",
1259
+ "card-themed": "polli:rounded-xl polli:bg-theme-bg-pale polli:p-4"
1260
+ };
1261
+ var Surface = ({
1262
+ theme,
1263
+ variant = "card",
1264
+ className,
1265
+ children,
1266
+ ...rest
1267
+ }) => /* @__PURE__ */ jsx16(
1268
+ "div",
1269
+ {
1270
+ ...rest,
1271
+ "data-theme": theme,
1272
+ className: cn("polli:min-w-0", variantClasses[variant], className),
1273
+ children
1274
+ }
1275
+ );
1276
+
1277
+ // src/compositions/LinkCard.tsx
1278
+ import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
1279
+ function isExternalHref(href) {
1280
+ return typeof href === "string" && /^https?:\/\//.test(href);
1281
+ }
1282
+ function LinkCard({
1283
+ as,
1284
+ theme,
1285
+ external,
1286
+ showIcon = true,
1287
+ className,
1288
+ surfaceClassName,
1289
+ children,
1290
+ ...linkProps
1291
+ }) {
1292
+ const Component = as || "a";
1293
+ const isExternal = external ?? isExternalHref(linkProps.href);
1294
+ return /* @__PURE__ */ jsx17(
1295
+ Component,
946
1296
  {
947
- ref,
948
- className: cn2(
949
- "polli:px-3 polli:py-2 polli:border polli:rounded-lg",
950
- "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
951
- error ? "polli:border-red-400" : "polli:border-gray-300",
952
- hideNumberSteppers && "polli-input-number-clean",
1297
+ "data-theme": theme,
1298
+ target: isExternal ? "_blank" : void 0,
1299
+ rel: isExternal ? "noopener noreferrer" : void 0,
1300
+ className: cn(
1301
+ "polli:group polli:block polli:h-full polli:rounded-xl polli:outline-none",
953
1302
  className
954
1303
  ),
1304
+ ...linkProps,
1305
+ children: /* @__PURE__ */ jsxs8(
1306
+ Surface,
1307
+ {
1308
+ theme,
1309
+ variant: "card",
1310
+ className: cn(
1311
+ "polli:relative polli:flex polli:h-full polli:flex-col polli:gap-2 polli:bg-surface-opaque/80 polli:p-5",
1312
+ showIcon && isExternal && "polli:pr-10",
1313
+ "polli:transition polli:group-hover:-translate-y-0.5 polli:group-hover:bg-surface-opaque/95",
1314
+ "polli:group-focus-visible:ring-2 polli:group-focus-visible:ring-theme-border",
1315
+ surfaceClassName
1316
+ ),
1317
+ children: [
1318
+ showIcon && isExternal && /* @__PURE__ */ jsx17(
1319
+ ExternalLinkIcon,
1320
+ {
1321
+ "aria-hidden": "true",
1322
+ className: "polli:absolute polli:top-4 polli:right-4 polli:h-3.5 polli:w-3.5 polli:text-theme-text-soft"
1323
+ }
1324
+ ),
1325
+ children
1326
+ ]
1327
+ }
1328
+ )
1329
+ }
1330
+ );
1331
+ }
1332
+
1333
+ // src/compositions/Markdown.tsx
1334
+ import ReactMarkdown from "react-markdown";
1335
+ import remarkGfm from "remark-gfm";
1336
+ import { jsx as jsx18 } from "react/jsx-runtime";
1337
+ var components = {
1338
+ ul: ({ node, ...props }) => /* @__PURE__ */ jsx18(
1339
+ "ul",
1340
+ {
1341
+ 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",
1342
+ ...props
1343
+ }
1344
+ ),
1345
+ ol: ({ node, ...props }) => /* @__PURE__ */ jsx18(
1346
+ "ol",
1347
+ {
1348
+ 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",
1349
+ ...props
1350
+ }
1351
+ ),
1352
+ p: ({ node, ...props }) => /* @__PURE__ */ jsx18("p", { className: "polli:mb-2 polli:last:mb-0", ...props }),
1353
+ strong: ({ node, ...props }) => /* @__PURE__ */ jsx18(
1354
+ "strong",
1355
+ {
1356
+ className: "polli:font-semibold polli:text-theme-text-strong",
1357
+ ...props
1358
+ }
1359
+ ),
1360
+ code: ({ node, ...props }) => /* @__PURE__ */ jsx18(
1361
+ "code",
1362
+ {
1363
+ className: "polli:break-words polli:rounded polli:bg-theme-bg-subtle polli:px-1 polli:py-0.5 polli:font-mono polli:text-xs",
1364
+ ...props
1365
+ }
1366
+ ),
1367
+ a: ({ node, ...props }) => /* @__PURE__ */ jsx18(
1368
+ "a",
1369
+ {
1370
+ target: "_blank",
1371
+ rel: "noopener noreferrer",
1372
+ className: "polli-control polli:rounded-sm polli:font-semibold polli:text-theme-text-strong polli:underline polli:underline-offset-2",
955
1373
  ...props
956
1374
  }
957
1375
  )
958
- );
959
-
960
- // src/primitives/ScrollArea.tsx
961
- import {
962
- forwardRef as forwardRef2,
963
- useCallback,
964
- useEffect as useEffect3,
965
- useRef as useRef3
966
- } from "react";
967
- import { jsx as jsx16 } from "react/jsx-runtime";
968
- var axisClasses = {
969
- y: "polli:overflow-y-auto polli:overflow-x-hidden",
970
- x: "polli:overflow-x-auto polli:overflow-y-hidden"
971
1376
  };
972
- function assignRef(ref, value) {
973
- if (typeof ref === "function") ref(value);
974
- else if (ref) ref.current = value;
1377
+ function Markdown({ children, className }) {
1378
+ return /* @__PURE__ */ jsx18(
1379
+ "div",
1380
+ {
1381
+ className: cn(
1382
+ "polli:min-w-0 polli:font-body polli:leading-relaxed",
1383
+ className
1384
+ ),
1385
+ children: /* @__PURE__ */ jsx18(ReactMarkdown, { remarkPlugins: [remarkGfm], components, children })
1386
+ }
1387
+ );
975
1388
  }
976
- var ScrollArea = forwardRef2(
977
- ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
978
- const innerRef = useRef3(null);
979
- const setRef = useCallback(
980
- (node) => {
981
- innerRef.current = node;
982
- assignRef(externalRef, node);
983
- },
984
- [externalRef]
985
- );
986
- useEffect3(() => {
987
- const element = innerRef.current;
988
- if (!element) return;
989
- let hideTimer = null;
990
- const clearHideTimer = () => {
991
- if (hideTimer !== null) {
992
- window.clearTimeout(hideTimer);
993
- hideTimer = null;
994
- }
995
- };
996
- const show = () => {
997
- element.dataset.scrollbarActive = "true";
998
- clearHideTimer();
999
- };
1000
- const hide = () => {
1001
- element.dataset.scrollbarActive = "false";
1002
- clearHideTimer();
1003
- };
1004
- const scheduleHide = () => {
1005
- clearHideTimer();
1006
- hideTimer = window.setTimeout(hide, 2e3);
1007
- };
1008
- const handleInteraction = () => {
1009
- show();
1010
- scheduleHide();
1011
- };
1012
- hide();
1013
- element.addEventListener("scroll", handleInteraction, {
1014
- passive: true
1015
- });
1016
- element.addEventListener("wheel", handleInteraction, {
1017
- passive: true
1018
- });
1019
- element.addEventListener("touchstart", handleInteraction, {
1020
- passive: true
1021
- });
1022
- element.addEventListener("pointerdown", handleInteraction);
1023
- element.addEventListener("keydown", handleInteraction);
1024
- element.addEventListener("focusin", handleInteraction);
1025
- element.addEventListener("focusout", scheduleHide);
1026
- return () => {
1027
- clearHideTimer();
1028
- element.removeEventListener("scroll", handleInteraction);
1029
- element.removeEventListener("wheel", handleInteraction);
1030
- element.removeEventListener("touchstart", handleInteraction);
1031
- element.removeEventListener("pointerdown", handleInteraction);
1032
- element.removeEventListener("keydown", handleInteraction);
1033
- element.removeEventListener("focusin", handleInteraction);
1034
- element.removeEventListener("focusout", scheduleHide);
1035
- };
1036
- }, []);
1037
- return /* @__PURE__ */ jsx16(
1038
- "div",
1039
- {
1040
- ...rest,
1041
- ref: setRef,
1042
- "data-theme": theme,
1043
- className: cn2(
1044
- "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
1045
- axisClasses[axis],
1046
- className
1047
- ),
1048
- children
1049
- }
1050
- );
1389
+
1390
+ // src/compositions/MediaPlaceholder.tsx
1391
+ import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
1392
+ var MediaPlaceholder = ({
1393
+ theme,
1394
+ icon,
1395
+ label,
1396
+ detail,
1397
+ action,
1398
+ children,
1399
+ className,
1400
+ ...rest
1401
+ }) => /* @__PURE__ */ jsxs9(
1402
+ "div",
1403
+ {
1404
+ ...rest,
1405
+ "data-theme": theme,
1406
+ className: cn(
1407
+ "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",
1408
+ className
1409
+ ),
1410
+ children: [
1411
+ icon && /* @__PURE__ */ jsx19("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 }),
1412
+ (label || detail) && /* @__PURE__ */ jsxs9("div", { className: "polli:max-w-sm", children: [
1413
+ label && /* @__PURE__ */ jsx19(Text, { as: "p", size: "sm", tone: "strong", weight: "semibold", children: label }),
1414
+ detail && /* @__PURE__ */ jsx19(Text, { as: "p", size: "sm", tone: "soft", className: "polli:mt-1", children: detail })
1415
+ ] }),
1416
+ children,
1417
+ action
1418
+ ]
1051
1419
  }
1052
1420
  );
1053
- ScrollArea.displayName = "ScrollArea";
1054
1421
 
1055
- // src/primitives/MultiSelect.tsx
1056
- import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
1057
- 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";
1058
- 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";
1422
+ // src/primitives/Dropdown.tsx
1423
+ import { Popover } from "@ark-ui/react/popover";
1424
+ import { Portal } from "@ark-ui/react/portal";
1425
+ import { useState as useState5 } from "react";
1426
+ import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
1427
+ var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
1428
+ var Dropdown = ({
1429
+ theme,
1430
+ trigger,
1431
+ children,
1432
+ align = "start",
1433
+ open: openProp,
1434
+ onOpenChange,
1435
+ className
1436
+ }) => {
1437
+ const [internalOpen, setInternalOpen] = useState5(false);
1438
+ const isControlled = openProp !== void 0;
1439
+ const open = isControlled ? openProp : internalOpen;
1440
+ const setOpen = (next) => {
1441
+ if (!isControlled) setInternalOpen(next);
1442
+ onOpenChange?.(next);
1443
+ };
1444
+ return /* @__PURE__ */ jsxs10(
1445
+ Popover.Root,
1446
+ {
1447
+ open,
1448
+ onOpenChange: (details) => setOpen(details.open),
1449
+ positioning: {
1450
+ placement: align === "end" ? "bottom-end" : "bottom-start"
1451
+ },
1452
+ children: [
1453
+ /* @__PURE__ */ jsx20(Popover.Trigger, { asChild: true, children: trigger(open) }),
1454
+ /* @__PURE__ */ jsx20(Portal, { children: /* @__PURE__ */ jsx20(Popover.Positioner, { children: /* @__PURE__ */ jsx20(
1455
+ Popover.Content,
1456
+ {
1457
+ "data-theme": theme,
1458
+ className: cn(
1459
+ "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
1460
+ DEFAULT_PANEL,
1461
+ className
1462
+ ),
1463
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
1464
+ }
1465
+ ) }) })
1466
+ ]
1467
+ }
1468
+ );
1469
+ };
1470
+
1471
+ // src/compositions/MultiSelect.tsx
1472
+ import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
1473
+ 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";
1474
+ 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";
1059
1475
  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";
1060
1476
  var MultiSelect = ({
1061
1477
  options,
@@ -1078,27 +1494,27 @@ var MultiSelect = ({
1078
1494
  };
1079
1495
  const selectAll = () => onChange([]);
1080
1496
  const displayText = disabled ? disabledText : isAllSelected ? "All" : `${selected.length} selected`;
1081
- const labelNode = label ? /* @__PURE__ */ jsx17("span", { className: "polli:text-xs polli:font-medium polli:text-theme-text-soft", children: label }) : null;
1497
+ const labelNode = label ? /* @__PURE__ */ jsx21("span", { className: "polli:text-xs polli:font-medium polli:text-theme-text-soft", children: label }) : null;
1082
1498
  if (disabled) {
1083
- return /* @__PURE__ */ jsxs8(
1499
+ return /* @__PURE__ */ jsxs11(
1084
1500
  "div",
1085
1501
  {
1086
1502
  "data-theme": theme,
1087
1503
  className: "polli:group polli:relative polli:flex polli:items-center polli:gap-2",
1088
1504
  children: [
1089
1505
  labelNode,
1090
- /* @__PURE__ */ jsxs8(
1506
+ /* @__PURE__ */ jsxs11(
1091
1507
  "button",
1092
1508
  {
1093
1509
  type: "button",
1094
1510
  disabled: true,
1095
- className: cn2(
1511
+ className: cn(
1096
1512
  TRIGGER_BASE,
1097
1513
  "polli:cursor-not-allowed polli:border-theme-border polli:bg-theme-bg-subtle polli:opacity-60"
1098
1514
  ),
1099
1515
  children: [
1100
- /* @__PURE__ */ jsx17("span", { className: "polli:flex-1 polli:truncate polli:text-left polli:text-theme-text-soft/60", children: displayText }),
1101
- /* @__PURE__ */ jsx17(
1516
+ /* @__PURE__ */ jsx21("span", { className: "polli:flex-1 polli:truncate polli:text-left polli:text-theme-text-soft/60", children: displayText }),
1517
+ /* @__PURE__ */ jsx21(
1102
1518
  ChevronIcon,
1103
1519
  {
1104
1520
  expanded: false,
@@ -1108,48 +1524,48 @@ var MultiSelect = ({
1108
1524
  ]
1109
1525
  }
1110
1526
  ),
1111
- /* @__PURE__ */ jsx17("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" })
1527
+ /* @__PURE__ */ jsx21("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" })
1112
1528
  ]
1113
1529
  }
1114
1530
  );
1115
1531
  }
1116
- return /* @__PURE__ */ jsxs8(
1532
+ return /* @__PURE__ */ jsxs11(
1117
1533
  "div",
1118
1534
  {
1119
1535
  "data-theme": theme,
1120
1536
  className: "polli:flex polli:items-center polli:gap-2",
1121
1537
  children: [
1122
1538
  labelNode,
1123
- /* @__PURE__ */ jsx17(
1539
+ /* @__PURE__ */ jsx21(
1124
1540
  Dropdown,
1125
1541
  {
1126
1542
  theme,
1127
1543
  align,
1128
1544
  className: "polli:min-w-[320px]",
1129
- trigger: (open) => /* @__PURE__ */ jsxs8(
1545
+ trigger: (open) => /* @__PURE__ */ jsxs11(
1130
1546
  "button",
1131
1547
  {
1132
1548
  type: "button",
1133
- className: cn2(
1549
+ className: cn(
1134
1550
  TRIGGER_BASE,
1135
1551
  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"
1136
1552
  ),
1137
1553
  children: [
1138
- /* @__PURE__ */ jsx17(
1554
+ /* @__PURE__ */ jsx21(
1139
1555
  "span",
1140
1556
  {
1141
- className: cn2(
1557
+ className: cn(
1142
1558
  "polli:flex-1 polli:truncate polli:text-left",
1143
1559
  open ? "polli:text-theme-text-strong" : "polli:text-theme-text-base"
1144
1560
  ),
1145
1561
  children: displayText
1146
1562
  }
1147
1563
  ),
1148
- /* @__PURE__ */ jsx17(
1564
+ /* @__PURE__ */ jsx21(
1149
1565
  ChevronIcon,
1150
1566
  {
1151
1567
  expanded: open,
1152
- className: cn2(
1568
+ className: cn(
1153
1569
  "polli:h-3 polli:w-3 polli:transition-transform",
1154
1570
  open ? "polli:text-theme-text-strong" : "polli:text-theme-text-soft"
1155
1571
  )
@@ -1158,21 +1574,21 @@ var MultiSelect = ({
1158
1574
  ]
1159
1575
  }
1160
1576
  ),
1161
- children: /* @__PURE__ */ jsxs8(ScrollArea, { theme, className: "polli:max-h-64", children: [
1162
- /* @__PURE__ */ jsxs8(
1577
+ children: /* @__PURE__ */ jsxs11(ScrollArea, { theme, className: "polli:max-h-64", children: [
1578
+ /* @__PURE__ */ jsxs11(
1163
1579
  "button",
1164
1580
  {
1165
1581
  type: "button",
1166
1582
  onClick: selectAll,
1167
- className: cn2(
1583
+ className: cn(
1168
1584
  ROW_BASE,
1169
1585
  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"
1170
1586
  ),
1171
1587
  children: [
1172
- /* @__PURE__ */ jsx17(
1588
+ /* @__PURE__ */ jsx21(
1173
1589
  "span",
1174
1590
  {
1175
- className: cn2(
1591
+ className: cn(
1176
1592
  CHECK_BASE,
1177
1593
  isAllSelected && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1178
1594
  ),
@@ -1185,27 +1601,27 @@ var MultiSelect = ({
1185
1601
  ),
1186
1602
  options.map((opt) => {
1187
1603
  const isChecked = selected.includes(opt.value);
1188
- return /* @__PURE__ */ jsxs8(
1604
+ return /* @__PURE__ */ jsxs11(
1189
1605
  "button",
1190
1606
  {
1191
1607
  type: "button",
1192
1608
  onClick: () => toggleItem(opt.value),
1193
- className: cn2(
1609
+ className: cn(
1194
1610
  ROW_BASE,
1195
1611
  isChecked ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-theme-text-base polli:hover:bg-theme-bg-subtle"
1196
1612
  ),
1197
1613
  children: [
1198
- /* @__PURE__ */ jsx17(
1614
+ /* @__PURE__ */ jsx21(
1199
1615
  "span",
1200
1616
  {
1201
- className: cn2(
1617
+ className: cn(
1202
1618
  CHECK_BASE,
1203
1619
  isChecked && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1204
1620
  ),
1205
1621
  children: isChecked && "\u2713"
1206
1622
  }
1207
1623
  ),
1208
- /* @__PURE__ */ jsx17("span", { className: "polli:whitespace-nowrap", children: opt.label })
1624
+ /* @__PURE__ */ jsx21("span", { className: "polli:whitespace-nowrap", children: opt.label })
1209
1625
  ]
1210
1626
  },
1211
1627
  opt.value
@@ -1219,26 +1635,179 @@ var MultiSelect = ({
1219
1635
  );
1220
1636
  };
1221
1637
 
1222
- // src/primitives/PeriodPicker.tsx
1223
- import { useEffect as useEffect4, useMemo, useState as useState4 } from "react";
1638
+ // src/compositions/NavItem.tsx
1639
+ import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
1640
+ 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";
1641
+ var activeClasses = "polli:bg-theme-bg-active polli:text-theme-text-strong";
1642
+ var inactiveClasses = "polli:text-ink-800 polli:hover:bg-surface-opaque/60 polli:hover:text-ink-950";
1643
+ 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";
1644
+ function NavItem({
1645
+ as,
1646
+ theme,
1647
+ active = false,
1648
+ className,
1649
+ children,
1650
+ ...rest
1651
+ }) {
1652
+ const Component = as || "button";
1653
+ return /* @__PURE__ */ jsxs12(
1654
+ Component,
1655
+ {
1656
+ "data-theme": theme,
1657
+ "aria-current": active ? "page" : void 0,
1658
+ className: cn(
1659
+ base,
1660
+ active ? activeClasses : inactiveClasses,
1661
+ className
1662
+ ),
1663
+ ...rest,
1664
+ children: [
1665
+ /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: dotClasses }),
1666
+ children
1667
+ ]
1668
+ }
1669
+ );
1670
+ }
1671
+
1672
+ // src/compositions/PeriodPicker.tsx
1673
+ import { useEffect as useEffect5, useMemo, useRef as useRef5, useState as useState6 } from "react";
1674
+
1675
+ // src/lib/period.ts
1676
+ var MS_PER_DAY = 864e5;
1677
+ function startOfUtcDay(date = /* @__PURE__ */ new Date()) {
1678
+ return new Date(
1679
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
1680
+ );
1681
+ }
1682
+ function addUtcDays(date, days) {
1683
+ const next = new Date(date);
1684
+ next.setUTCDate(next.getUTCDate() + days);
1685
+ return next;
1686
+ }
1687
+ function startOfUtcMonth(date) {
1688
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
1689
+ }
1690
+ function addUtcMonths(date, months) {
1691
+ return new Date(
1692
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
1693
+ );
1694
+ }
1695
+ function startOfUtcIsoWeek(date) {
1696
+ const day = date.getUTCDay() || 7;
1697
+ return addUtcDays(startOfUtcDay(date), 1 - day);
1698
+ }
1699
+ function getUtcIsoWeekPeriod(date) {
1700
+ const day = date.getUTCDay() || 7;
1701
+ const thursday = addUtcDays(startOfUtcDay(date), 4 - day);
1702
+ const isoYear = thursday.getUTCFullYear();
1703
+ const yearStart = new Date(Date.UTC(isoYear, 0, 1));
1704
+ const isoWeek = Math.ceil(
1705
+ ((thursday.getTime() - yearStart.getTime()) / MS_PER_DAY + 1) / 7
1706
+ );
1707
+ return `${isoYear}-W${String(isoWeek).padStart(2, "0")}`;
1708
+ }
1709
+ function formatUtcDatePeriod(date) {
1710
+ return date.toISOString().slice(0, 10);
1711
+ }
1712
+ function formatUtcHourPeriod(date) {
1713
+ return date.toISOString().slice(0, 13).replace("T", " ");
1714
+ }
1715
+ function formatUtcMonthPeriod(date) {
1716
+ return date.toISOString().slice(0, 7);
1717
+ }
1718
+ function periodFromDate(granularity, date = /* @__PURE__ */ new Date()) {
1719
+ if (granularity === "day") {
1720
+ return {
1721
+ granularity,
1722
+ period: formatUtcDatePeriod(startOfUtcDay(date))
1723
+ };
1724
+ }
1725
+ if (granularity === "week") {
1726
+ return { granularity, period: getUtcIsoWeekPeriod(date) };
1727
+ }
1728
+ return { granularity, period: formatUtcMonthPeriod(startOfUtcMonth(date)) };
1729
+ }
1730
+ function currentPeriod() {
1731
+ return periodFromDate("day");
1732
+ }
1733
+ function periodToWindow(selection) {
1734
+ if (selection.granularity === "day") {
1735
+ const start2 = /* @__PURE__ */ new Date(`${selection.period}T00:00:00.000Z`);
1736
+ return { start: start2, end: addUtcDays(start2, 1) };
1737
+ }
1738
+ if (selection.granularity === "week") {
1739
+ const [yearText2, weekText] = selection.period.split("-W");
1740
+ const isoYear = Number(yearText2);
1741
+ const isoWeek = Number(weekText);
1742
+ const jan4 = new Date(Date.UTC(isoYear, 0, 4));
1743
+ const start2 = addUtcDays(startOfUtcIsoWeek(jan4), (isoWeek - 1) * 7);
1744
+ return { start: start2, end: addUtcDays(start2, 7) };
1745
+ }
1746
+ const [yearText, monthText] = selection.period.split("-");
1747
+ const start = new Date(
1748
+ Date.UTC(Number(yearText), Number(monthText) - 1, 1)
1749
+ );
1750
+ return { start, end: addUtcMonths(start, 1) };
1751
+ }
1752
+ function getPeriodBucketKeys(selection) {
1753
+ const { start, end } = periodToWindow(selection);
1754
+ const bucketKeys = [];
1755
+ const cursor = new Date(start);
1756
+ if (selection.granularity === "day") {
1757
+ while (cursor < end) {
1758
+ bucketKeys.push(`${formatUtcHourPeriod(cursor)}:00:00`);
1759
+ cursor.setUTCHours(cursor.getUTCHours() + 1);
1760
+ }
1761
+ return bucketKeys;
1762
+ }
1763
+ while (cursor < end) {
1764
+ bucketKeys.push(formatUtcDatePeriod(cursor));
1765
+ cursor.setUTCDate(cursor.getUTCDate() + 1);
1766
+ }
1767
+ return bucketKeys;
1768
+ }
1769
+ function periodBucketKeyToDate(bucketKey, granularity) {
1770
+ if (granularity === "day") {
1771
+ return /* @__PURE__ */ new Date(`${bucketKey.replace(" ", "T")}.000Z`);
1772
+ }
1773
+ return /* @__PURE__ */ new Date(`${bucketKey}T00:00:00.000Z`);
1774
+ }
1775
+ function isPeriodSelectable(selection, minDate = /* @__PURE__ */ new Date(0), maxDate = startOfUtcDay()) {
1776
+ const { start, end } = periodToWindow(selection);
1777
+ return end > minDate && start <= maxDate;
1778
+ }
1224
1779
 
1225
1780
  // src/primitives/TabButton.tsx
1226
- import { jsx as jsx18 } from "react/jsx-runtime";
1227
- var sizeClasses2 = {
1228
- medium: "polli:px-4 polli:py-1.5 polli:text-base",
1229
- small: "polli:px-3 polli:py-1.5 polli:text-sm"
1781
+ import { jsx as jsx23 } from "react/jsx-runtime";
1782
+ var sizeClasses = {
1783
+ md: "polli:px-4 polli:py-1.5 polli:text-base",
1784
+ sm: "polli:px-3 polli:py-1.5 polli:text-sm"
1785
+ };
1786
+ var variantClasses2 = {
1787
+ default: {
1788
+ base: "polli:border",
1789
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border",
1790
+ inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active"
1791
+ },
1792
+ ghost: {
1793
+ base: "polli:border polli:border-transparent",
1794
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong",
1795
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong"
1796
+ }
1230
1797
  };
1231
1798
  var TabButton = ({
1232
1799
  theme,
1233
1800
  active,
1234
1801
  onClick,
1235
1802
  children,
1236
- size = "medium",
1803
+ size = "md",
1804
+ variant = "default",
1237
1805
  ariaLabel,
1238
1806
  disabled = false,
1239
1807
  className
1240
1808
  }) => {
1241
- return /* @__PURE__ */ jsx18(
1809
+ const classes = variantClasses2[variant];
1810
+ return /* @__PURE__ */ jsx23(
1242
1811
  "button",
1243
1812
  {
1244
1813
  type: "button",
@@ -1247,11 +1816,12 @@ var TabButton = ({
1247
1816
  "aria-label": ariaLabel,
1248
1817
  "aria-pressed": active,
1249
1818
  disabled,
1250
- className: cn2(
1251
- "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",
1252
- 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",
1819
+ className: cn(
1820
+ "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",
1821
+ classes.base,
1822
+ active ? classes.active : classes.inactive,
1253
1823
  disabled && "polli:cursor-not-allowed polli:opacity-50",
1254
- sizeClasses2[size],
1824
+ sizeClasses[size],
1255
1825
  className
1256
1826
  ),
1257
1827
  children
@@ -1259,8 +1829,8 @@ var TabButton = ({
1259
1829
  );
1260
1830
  };
1261
1831
 
1262
- // src/primitives/PeriodPicker.tsx
1263
- import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
1832
+ // src/compositions/PeriodPicker.tsx
1833
+ import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
1264
1834
  var WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
1265
1835
  var MONTH_LABELS = [
1266
1836
  "Jan",
@@ -1276,7 +1846,7 @@ var MONTH_LABELS = [
1276
1846
  "Nov",
1277
1847
  "Dec"
1278
1848
  ];
1279
- 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";
1849
+ 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";
1280
1850
  function addUtcMonths2(date, months) {
1281
1851
  return new Date(
1282
1852
  Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
@@ -1296,6 +1866,42 @@ function sameUtcDay(left, right) {
1296
1866
  function periodDate(value) {
1297
1867
  return periodToWindow(value).start;
1298
1868
  }
1869
+ function selectionKey(value) {
1870
+ return `${value.granularity}:${value.period}`;
1871
+ }
1872
+ function formatMonthYear(date, month = "short") {
1873
+ return date.toLocaleDateString("en-US", {
1874
+ timeZone: "UTC",
1875
+ month,
1876
+ year: "numeric"
1877
+ });
1878
+ }
1879
+ function formatFullDate(date) {
1880
+ return date.toLocaleDateString("en-US", {
1881
+ timeZone: "UTC",
1882
+ month: "short",
1883
+ day: "numeric",
1884
+ year: "numeric"
1885
+ });
1886
+ }
1887
+ function formatWeekSummary(start, end) {
1888
+ const weekEnd = addUtcDays(end, -1);
1889
+ const sameMonth = start.getUTCFullYear() === weekEnd.getUTCFullYear() && start.getUTCMonth() === weekEnd.getUTCMonth();
1890
+ if (sameMonth) {
1891
+ const month = start.toLocaleDateString("en-US", {
1892
+ timeZone: "UTC",
1893
+ month: "short"
1894
+ });
1895
+ return `${month} ${start.getUTCDate()}-${weekEnd.getUTCDate()}, ${weekEnd.getUTCFullYear()}`;
1896
+ }
1897
+ return `${formatFullDate(start)} - ${formatFullDate(weekEnd)}`;
1898
+ }
1899
+ function formatPeriodSummary(value) {
1900
+ const { start, end } = periodToWindow(value);
1901
+ if (value.granularity === "day") return formatFullDate(start);
1902
+ if (value.granularity === "week") return formatWeekSummary(start, end);
1903
+ return formatMonthYear(start, "long");
1904
+ }
1299
1905
  function viewBounds(viewDate, granularity) {
1300
1906
  if (granularity === "month") {
1301
1907
  const start2 = new Date(Date.UTC(viewDate.getUTCFullYear(), 0, 1));
@@ -1313,11 +1919,20 @@ var PeriodPicker = ({
1313
1919
  minDate = /* @__PURE__ */ new Date(0),
1314
1920
  maxDate
1315
1921
  }) => {
1316
- const [open, setOpen] = useState4(false);
1317
- const [viewDate, setViewDate] = useState4(() => periodDate(value));
1922
+ const [open, setOpen] = useState6(false);
1923
+ const [viewDate, setViewDate] = useState6(() => periodDate(value));
1924
+ const [anchorDate, setAnchorDate] = useState6(() => periodDate(value));
1925
+ const emittedSelectionRef = useRef5(null);
1318
1926
  const { granularity, period } = value;
1319
- useEffect4(() => {
1320
- setViewDate(periodDate({ granularity, period }));
1927
+ useEffect5(() => {
1928
+ const currentSelectionKey = selectionKey({ granularity, period });
1929
+ if (emittedSelectionRef.current === currentSelectionKey) {
1930
+ emittedSelectionRef.current = null;
1931
+ return;
1932
+ }
1933
+ const nextAnchorDate = periodDate({ granularity, period });
1934
+ setAnchorDate(nextAnchorDate);
1935
+ setViewDate(nextAnchorDate);
1321
1936
  }, [granularity, period]);
1322
1937
  const dates = useMemo(() => monthGridDates(viewDate), [viewDate]);
1323
1938
  const selectedWindow = periodToWindow(value);
@@ -1328,26 +1943,29 @@ var PeriodPicker = ({
1328
1943
  const nextBounds = viewBounds(nextViewDate, value.granularity);
1329
1944
  const previousDisabled = previousBounds.end <= minDate;
1330
1945
  const nextDisabled = nextBounds.start > today;
1946
+ const summaryLabel = formatPeriodSummary(value);
1947
+ const commitSelection = (selection, anchor) => {
1948
+ emittedSelectionRef.current = selectionKey(selection);
1949
+ setAnchorDate(anchor);
1950
+ setViewDate(anchor);
1951
+ onChange(selection);
1952
+ };
1331
1953
  const setGranularity = (granularity2) => {
1332
- onChange(periodFromDate(granularity2, periodDate(value)));
1954
+ commitSelection(periodFromDate(granularity2, anchorDate), anchorDate);
1333
1955
  };
1334
1956
  const selectDate = (date) => {
1335
- onChange(periodFromDate(value.granularity, date));
1957
+ commitSelection(periodFromDate(value.granularity, date), date);
1336
1958
  setOpen(false);
1337
1959
  };
1338
- const viewLabel = value.granularity === "month" ? String(viewDate.getUTCFullYear()) : viewDate.toLocaleDateString("en-US", {
1339
- timeZone: "UTC",
1340
- month: "long",
1341
- year: "numeric"
1342
- });
1343
- return /* @__PURE__ */ jsxs9(
1960
+ const viewLabel = value.granularity === "month" ? String(viewDate.getUTCFullYear()) : formatMonthYear(viewDate, "long");
1961
+ return /* @__PURE__ */ jsxs13(
1344
1962
  "div",
1345
1963
  {
1346
1964
  "data-theme": theme,
1347
1965
  className: "polli:flex polli:flex-wrap polli:items-center polli:gap-2",
1348
1966
  children: [
1349
- /* @__PURE__ */ jsx19("div", { className: "polli:flex polli:flex-wrap polli:gap-1.5", children: ["day", "week", "month"].map(
1350
- (granularity2) => /* @__PURE__ */ jsx19(
1967
+ /* @__PURE__ */ jsx24("div", { className: "polli:flex polli:flex-wrap polli:gap-1.5", children: ["day", "week", "month"].map(
1968
+ (granularity2) => /* @__PURE__ */ jsx24(
1351
1969
  TabButton,
1352
1970
  {
1353
1971
  active: value.granularity === granularity2,
@@ -1357,55 +1975,55 @@ var PeriodPicker = ({
1357
1975
  granularity2
1358
1976
  )
1359
1977
  ) }),
1360
- /* @__PURE__ */ jsxs9(
1978
+ /* @__PURE__ */ jsxs13(
1361
1979
  Dropdown,
1362
1980
  {
1363
1981
  theme,
1364
1982
  open,
1365
1983
  onOpenChange: setOpen,
1366
- className: "polli:w-[304px] polli:rounded-xl polli:p-3",
1367
- trigger: (isOpen) => /* @__PURE__ */ jsxs9(
1984
+ className: "polli:w-[320px] polli:rounded-xl polli:p-3.5",
1985
+ trigger: (isOpen) => /* @__PURE__ */ jsxs13(
1368
1986
  "button",
1369
1987
  {
1370
1988
  type: "button",
1371
- "aria-label": `Select period, current ${formatPeriodLabel(value)}`,
1372
- className: cn2(
1373
- "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",
1989
+ "aria-label": `Select period, current ${summaryLabel}`,
1990
+ className: cn(
1991
+ "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",
1374
1992
  "polli:border-theme-border polli:bg-theme-bg-subtle polli:text-theme-text-base",
1375
1993
  "polli:transition-all polli:duration-200 polli:ease-out polli:hover:bg-theme-bg-pale",
1376
1994
  isOpen && "polli:bg-theme-bg-active polli:text-theme-text-strong polli:shadow-sm"
1377
1995
  ),
1378
1996
  children: [
1379
- /* @__PURE__ */ jsx19("span", { children: formatPeriodLabel(value) }),
1380
- /* @__PURE__ */ jsx19(ChevronIcon, { expanded: isOpen })
1997
+ /* @__PURE__ */ jsx24("span", { className: "polli:truncate", children: summaryLabel }),
1998
+ /* @__PURE__ */ jsx24(ChevronIcon, { expanded: isOpen })
1381
1999
  ]
1382
2000
  }
1383
2001
  ),
1384
2002
  children: [
1385
- /* @__PURE__ */ jsxs9("div", { className: "polli:mb-3 polli:flex polli:items-center polli:justify-between", children: [
1386
- /* @__PURE__ */ jsx19(
2003
+ /* @__PURE__ */ jsxs13("div", { className: "polli:mb-3 polli:flex polli:items-center polli:justify-between", children: [
2004
+ /* @__PURE__ */ jsx24(
1387
2005
  "button",
1388
2006
  {
1389
2007
  type: "button",
1390
- "aria-label": value.granularity === "month" ? "Previous year" : "Previous month",
2008
+ "aria-label": "Previous",
1391
2009
  disabled: previousDisabled,
1392
2010
  onClick: () => setViewDate(previousViewDate),
1393
- className: cn2(
2011
+ className: cn(
1394
2012
  NAV_BUTTON,
1395
2013
  previousDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1396
2014
  ),
1397
2015
  children: "<"
1398
2016
  }
1399
2017
  ),
1400
- /* @__PURE__ */ jsx19("div", { className: "polli:text-sm polli:font-bold polli:text-theme-text-base", children: viewLabel }),
1401
- /* @__PURE__ */ jsx19(
2018
+ /* @__PURE__ */ jsx24("div", { className: "polli:text-base polli:font-bold polli:text-theme-text-base", children: viewLabel }),
2019
+ /* @__PURE__ */ jsx24(
1402
2020
  "button",
1403
2021
  {
1404
2022
  type: "button",
1405
- "aria-label": value.granularity === "month" ? "Next year" : "Next month",
2023
+ "aria-label": "Next",
1406
2024
  disabled: nextDisabled,
1407
2025
  onClick: () => setViewDate(nextViewDate),
1408
- className: cn2(
2026
+ className: cn(
1409
2027
  NAV_BUTTON,
1410
2028
  nextDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1411
2029
  ),
@@ -1413,7 +2031,7 @@ var PeriodPicker = ({
1413
2031
  }
1414
2032
  )
1415
2033
  ] }),
1416
- value.granularity === "month" ? /* @__PURE__ */ jsx19("div", { className: "polli:grid polli:grid-cols-3 polli:gap-1.5", children: MONTH_LABELS.map((label, monthIndex) => {
2034
+ value.granularity === "month" ? /* @__PURE__ */ jsx24("div", { className: "polli:grid polli:grid-cols-3 polli:gap-1.5", children: MONTH_LABELS.map((label, monthIndex) => {
1417
2035
  const date = new Date(
1418
2036
  Date.UTC(
1419
2037
  viewDate.getUTCFullYear(),
@@ -1432,32 +2050,32 @@ var PeriodPicker = ({
1432
2050
  year: "numeric"
1433
2051
  });
1434
2052
  const selected = date.getUTCFullYear() === selectedWindow.start.getUTCFullYear() && date.getUTCMonth() === selectedWindow.start.getUTCMonth();
1435
- return /* @__PURE__ */ jsx19(
2053
+ return /* @__PURE__ */ jsx24(
1436
2054
  "button",
1437
2055
  {
1438
2056
  type: "button",
1439
2057
  "aria-label": ariaLabel,
1440
2058
  disabled: !selectable,
1441
2059
  onClick: () => selectDate(date),
1442
- className: cn2(
1443
- "polli:rounded-lg polli:px-3 polli:py-2 polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1444
- selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1445
- !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
2060
+ className: cn(
2061
+ "polli-control polli:rounded-lg polli:px-3 polli:py-2 polli:text-sm polli:font-medium polli:transition-colors polli:duration-150",
2062
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-ink-700 polli:hover:bg-theme-bg-subtle",
2063
+ !selectable && "polli:cursor-not-allowed polli:text-ink-300 polli:hover:bg-transparent"
1446
2064
  ),
1447
2065
  children: label
1448
2066
  },
1449
2067
  label
1450
2068
  );
1451
- }) }) : /* @__PURE__ */ jsxs9(Fragment2, { children: [
1452
- /* @__PURE__ */ jsx19("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__ */ jsx19("div", { children: label }, label)) }),
1453
- /* @__PURE__ */ jsx19("div", { className: "polli:grid polli:grid-cols-7 polli:gap-1", children: dates.map((date) => {
2069
+ }) }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
2070
+ /* @__PURE__ */ jsx24("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__ */ jsx24("div", { children: label }, label)) }),
2071
+ /* @__PURE__ */ jsx24("div", { className: "polli:grid polli:grid-cols-7 polli:gap-1", children: dates.map((date) => {
1454
2072
  const inCurrentMonth = date.getUTCMonth() === viewDate.getUTCMonth();
1455
2073
  const selectable = isPeriodSelectable(
1456
2074
  periodFromDate(value.granularity, date),
1457
2075
  minDate,
1458
2076
  today
1459
2077
  );
1460
- const ariaLabel = value.granularity === "week" ? `Select week ${formatPeriodLabel(periodFromDate("week", date))}` : `Select ${date.toLocaleDateString(
2078
+ const ariaLabel = value.granularity === "week" ? `Select ${formatPeriodSummary(periodFromDate("week", date))}` : `Select ${date.toLocaleDateString(
1461
2079
  "en-US",
1462
2080
  {
1463
2081
  timeZone: "UTC",
@@ -1468,19 +2086,19 @@ var PeriodPicker = ({
1468
2086
  }
1469
2087
  )}`;
1470
2088
  const selected = value.granularity === "day" ? sameUtcDay(date, selectedWindow.start) : date >= selectedWindow.start && date < selectedWindow.end;
1471
- return /* @__PURE__ */ jsx19(
2089
+ return /* @__PURE__ */ jsx24(
1472
2090
  "button",
1473
2091
  {
1474
2092
  type: "button",
1475
2093
  "aria-label": ariaLabel,
1476
2094
  disabled: !selectable,
1477
2095
  onClick: () => selectDate(date),
1478
- className: cn2(
1479
- "polli:aspect-square polli:rounded-lg polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1480
- !inCurrentMonth && "polli:text-gray-300",
2096
+ className: cn(
2097
+ "polli-control polli:aspect-square polli:rounded-lg polli:text-sm polli:font-medium polli:transition-colors polli:duration-150",
2098
+ !inCurrentMonth && "polli:text-ink-300",
1481
2099
  sameUtcDay(date, today) && "polli:ring-1 polli:ring-theme-border",
1482
- selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1483
- !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
2100
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-ink-700 polli:hover:bg-theme-bg-subtle",
2101
+ !selectable && "polli:cursor-not-allowed polli:text-ink-300 polli:hover:bg-transparent"
1484
2102
  ),
1485
2103
  children: date.getUTCDate()
1486
2104
  },
@@ -1496,58 +2114,517 @@ var PeriodPicker = ({
1496
2114
  );
1497
2115
  };
1498
2116
 
1499
- // src/primitives/Surface.tsx
1500
- import { jsx as jsx20 } from "react/jsx-runtime";
1501
- var variantClasses = {
1502
- panel: "polli:rounded-2xl polli:border polli:border-theme-border polli:bg-theme-bg-subtle polli:p-6",
1503
- card: "polli:rounded-xl polli:bg-surface-white polli:p-4",
1504
- "card-themed": "polli:rounded-xl polli:bg-theme-bg-pale polli:p-4"
2117
+ // src/compositions/Prose.tsx
2118
+ import Markdown2 from "react-markdown";
2119
+ import rehypeSlug from "rehype-slug";
2120
+ import remarkGfm2 from "remark-gfm";
2121
+ import { jsx as jsx25 } from "react/jsx-runtime";
2122
+ var components2 = {
2123
+ h1: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2124
+ "h1",
2125
+ {
2126
+ className: headingClassName("title", "polli:mt-0 polli:mb-5"),
2127
+ ...props
2128
+ }
2129
+ ),
2130
+ h2: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2131
+ "h2",
2132
+ {
2133
+ className: headingClassName("section", "polli:mt-8 polli:mb-3"),
2134
+ ...props
2135
+ }
2136
+ ),
2137
+ h3: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2138
+ "h3",
2139
+ {
2140
+ className: headingClassName("subsection", "polli:mt-6 polli:mb-2"),
2141
+ ...props
2142
+ }
2143
+ ),
2144
+ p: ({ node, ...props }) => /* @__PURE__ */ jsx25("p", { className: "polli:my-4 polli:leading-relaxed", ...props }),
2145
+ a: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2146
+ "a",
2147
+ {
2148
+ 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",
2149
+ ...props
2150
+ }
2151
+ ),
2152
+ ul: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2153
+ "ul",
2154
+ {
2155
+ className: "polli:my-4 polli:list-disc polli:pl-6 polli:leading-relaxed",
2156
+ ...props
2157
+ }
2158
+ ),
2159
+ ol: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2160
+ "ol",
2161
+ {
2162
+ className: "polli:my-4 polli:list-decimal polli:pl-6 polli:leading-relaxed",
2163
+ ...props
2164
+ }
2165
+ ),
2166
+ blockquote: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2167
+ "blockquote",
2168
+ {
2169
+ className: "polli:my-4 polli:border-l-4 polli:border-theme-border polli:pl-4 polli:text-theme-text-soft",
2170
+ ...props
2171
+ }
2172
+ ),
2173
+ code: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2174
+ "code",
2175
+ {
2176
+ className: "polli:rounded polli:bg-theme-bg-active polli:px-1 polli:py-0.5 polli:font-pixel polli:text-sm",
2177
+ ...props
2178
+ }
2179
+ ),
2180
+ pre: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2181
+ "pre",
2182
+ {
2183
+ className: "polli:my-4 polli:overflow-x-auto polli:rounded-lg polli:bg-theme-bg-active polli:p-4",
2184
+ ...props
2185
+ }
2186
+ ),
2187
+ table: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2188
+ "table",
2189
+ {
2190
+ className: "polli:my-4 polli:w-full polli:border-collapse polli:text-sm",
2191
+ ...props
2192
+ }
2193
+ ),
2194
+ th: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2195
+ "th",
2196
+ {
2197
+ className: "polli:border polli:border-theme-border polli:px-3 polli:py-2 polli:text-left polli:font-semibold",
2198
+ ...props
2199
+ }
2200
+ ),
2201
+ td: ({ node, ...props }) => /* @__PURE__ */ jsx25(
2202
+ "td",
2203
+ {
2204
+ className: "polli:border polli:border-theme-border polli:px-3 polli:py-2",
2205
+ ...props
2206
+ }
2207
+ ),
2208
+ hr: ({ node, ...props }) => /* @__PURE__ */ jsx25("hr", { className: "polli:my-6 polli:border-theme-border", ...props })
2209
+ };
2210
+ function Prose({ children, className }) {
2211
+ return /* @__PURE__ */ jsx25(
2212
+ "div",
2213
+ {
2214
+ className: cn(
2215
+ "polli:font-body polli:text-theme-text-base polli:leading-relaxed",
2216
+ className
2217
+ ),
2218
+ children: /* @__PURE__ */ jsx25(
2219
+ Markdown2,
2220
+ {
2221
+ remarkPlugins: [remarkGfm2],
2222
+ rehypePlugins: [rehypeSlug],
2223
+ components: components2,
2224
+ children
2225
+ }
2226
+ )
2227
+ }
2228
+ );
2229
+ }
2230
+
2231
+ // src/compositions/Section.tsx
2232
+ import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
2233
+ var Section = ({
2234
+ title,
2235
+ theme,
2236
+ id,
2237
+ framed = false,
2238
+ intro,
2239
+ action,
2240
+ actionClassName,
2241
+ panelClassName,
2242
+ titleClassName,
2243
+ children,
2244
+ className
2245
+ }) => /* @__PURE__ */ jsxs14(
2246
+ "section",
2247
+ {
2248
+ id,
2249
+ className: cn(
2250
+ "polli:flex polli:scroll-mt-10 polli:flex-col polli:gap-4",
2251
+ className
2252
+ ),
2253
+ children: [
2254
+ /* @__PURE__ */ jsxs14("header", { className: "polli:flex polli:flex-wrap polli:items-center polli:justify-between polli:gap-3 polli:px-1", children: [
2255
+ /* @__PURE__ */ jsx26(
2256
+ Heading,
2257
+ {
2258
+ as: "h2",
2259
+ "data-theme": theme,
2260
+ size: "section",
2261
+ className: cn("polli:text-left", titleClassName),
2262
+ children: title
2263
+ }
2264
+ ),
2265
+ action && /* @__PURE__ */ jsx26("div", { className: cn("polli:shrink-0", actionClassName), children: action })
2266
+ ] }),
2267
+ framed ? /* @__PURE__ */ jsxs14(
2268
+ Surface,
2269
+ {
2270
+ variant: "panel",
2271
+ theme,
2272
+ className: cn(
2273
+ "polli:flex polli:flex-col polli:gap-5",
2274
+ panelClassName
2275
+ ),
2276
+ children: [
2277
+ intro && /* @__PURE__ */ jsx26(Text, { as: "div", className: "polli:max-w-2xl", children: intro }),
2278
+ children
2279
+ ]
2280
+ }
2281
+ ) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
2282
+ intro && /* @__PURE__ */ jsx26(
2283
+ Text,
2284
+ {
2285
+ as: "div",
2286
+ "data-theme": theme,
2287
+ className: "polli:max-w-2xl",
2288
+ children: intro
2289
+ }
2290
+ ),
2291
+ children
2292
+ ] })
2293
+ ]
2294
+ }
2295
+ );
2296
+
2297
+ // src/compositions/StatCard.tsx
2298
+ import { jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
2299
+ var valueVariantClasses = {
2300
+ stat: "polli:min-h-8 polli:text-2xl polli:font-bold polli:leading-tight polli:tabular-nums polli:text-theme-text-strong",
2301
+ fact: "polli:text-sm polli:leading-6 polli:text-theme-text-soft"
1505
2302
  };
1506
- var Surface = ({
2303
+ var StatCard = ({
2304
+ label,
2305
+ value,
2306
+ detail,
2307
+ variant = "stat",
1507
2308
  theme,
1508
- variant = "card",
2309
+ className,
2310
+ labelClassName,
2311
+ valueClassName,
2312
+ detailClassName
2313
+ }) => /* @__PURE__ */ jsxs15("div", { "data-theme": theme, className: cn("polli:text-sm", className), children: [
2314
+ /* @__PURE__ */ jsx27(
2315
+ Text,
2316
+ {
2317
+ as: "div",
2318
+ size: "micro",
2319
+ tone: "strong",
2320
+ weight: "bold",
2321
+ className: cn(
2322
+ "polli:uppercase polli:tracking-wide",
2323
+ labelClassName
2324
+ ),
2325
+ children: label
2326
+ }
2327
+ ),
2328
+ /* @__PURE__ */ jsx27(
2329
+ "div",
2330
+ {
2331
+ className: cn(
2332
+ "polli:mt-1 polli:break-words",
2333
+ valueVariantClasses[variant],
2334
+ valueClassName
2335
+ ),
2336
+ children: value
2337
+ }
2338
+ ),
2339
+ detail && /* @__PURE__ */ jsx27(
2340
+ Text,
2341
+ {
2342
+ as: "div",
2343
+ size: "xs",
2344
+ tone: "soft",
2345
+ className: cn("polli:mt-2", detailClassName),
2346
+ children: detail
2347
+ }
2348
+ )
2349
+ ] });
2350
+
2351
+ // src/lib/cn-app.ts
2352
+ import { clsx as clsx2 } from "clsx";
2353
+ import { twMerge as twMerge2 } from "tailwind-merge";
2354
+ function cn2(...inputs) {
2355
+ return twMerge2(clsx2(...inputs));
2356
+ }
2357
+
2358
+ // src/lib/use-scroll-lock.ts
2359
+ import { useEffect as useEffect6 } from "react";
2360
+ function useScrollLock(enabled = true) {
2361
+ useEffect6(() => {
2362
+ if (!enabled) return;
2363
+ const originalBody = document.body.style.overflow;
2364
+ const originalHtml = document.documentElement.style.overflow;
2365
+ document.body.style.overflow = "hidden";
2366
+ document.documentElement.style.overflow = "hidden";
2367
+ return () => {
2368
+ document.body.style.overflow = originalBody;
2369
+ document.documentElement.style.overflow = originalHtml;
2370
+ };
2371
+ }, [enabled]);
2372
+ }
2373
+
2374
+ // src/primitives/ButtonGroup.tsx
2375
+ import { jsx as jsx28 } from "react/jsx-runtime";
2376
+ var ButtonGroup = ({
2377
+ wrap = true,
1509
2378
  className,
1510
2379
  children,
2380
+ role = "group",
1511
2381
  ...rest
1512
- }) => /* @__PURE__ */ jsx20(
2382
+ }) => /* @__PURE__ */ jsx28(
1513
2383
  "div",
1514
2384
  {
1515
2385
  ...rest,
1516
- "data-theme": theme,
1517
- className: cn2("polli:min-w-0", variantClasses[variant], className),
2386
+ role,
2387
+ className: cn(
2388
+ "polli:flex polli:min-w-0 polli:items-center polli:gap-1.5",
2389
+ wrap ? "polli:flex-wrap" : "polli:flex-nowrap",
2390
+ className
2391
+ ),
1518
2392
  children
1519
2393
  }
1520
2394
  );
1521
2395
 
1522
- // src/primitives/Section.tsx
1523
- import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
1524
- var Section = ({
2396
+ // src/primitives/Chip.tsx
2397
+ import { jsx as jsx29 } from "react/jsx-runtime";
2398
+ var chipSizes = {
2399
+ sm: "polli:px-2 polli:py-0.5 polli:text-xs",
2400
+ md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
2401
+ lg: "polli:px-3 polli:py-1 polli:text-sm"
2402
+ };
2403
+ var intentClasses4 = {
2404
+ news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
2405
+ alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
2406
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
2407
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
2408
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
2409
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
2410
+ };
2411
+ var Chip = ({
2412
+ theme,
2413
+ intent,
2414
+ size = "md",
2415
+ className,
2416
+ children,
2417
+ ...rest
2418
+ }) => {
2419
+ const intentClass = intent ? intentClasses4[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
2420
+ return /* @__PURE__ */ jsx29(
2421
+ "span",
2422
+ {
2423
+ ...rest,
2424
+ "data-theme": theme,
2425
+ className: cn(
2426
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
2427
+ chipSizes[size],
2428
+ intentClass,
2429
+ className
2430
+ ),
2431
+ children
2432
+ }
2433
+ );
2434
+ };
2435
+
2436
+ // src/primitives/Dialog.tsx
2437
+ import { Dialog as ArkDialog } from "@ark-ui/react/dialog";
2438
+ import { Portal as Portal2 } from "@ark-ui/react/portal";
2439
+ import { useRef as useRef6 } from "react";
2440
+ import { jsx as jsx30, jsxs as jsxs16 } from "react/jsx-runtime";
2441
+ var sizeClasses2 = {
2442
+ sm: "polli:max-w-md",
2443
+ md: "polli:max-w-xl",
2444
+ lg: "polli:max-w-2xl"
2445
+ };
2446
+ var Dialog = ({
2447
+ open,
2448
+ onOpenChange,
2449
+ trigger,
2450
+ triggerAsChild = false,
2451
+ triggerClassName,
1525
2452
  title,
2453
+ titleClassName,
2454
+ ariaLabel,
2455
+ labelledBy,
2456
+ theme = "blue",
2457
+ size = "md",
2458
+ showBackdrop = true,
2459
+ backdropClassName,
2460
+ positionerClassName,
2461
+ contentClassName,
2462
+ children
2463
+ }) => {
2464
+ const contentRef = useRef6(null);
2465
+ return /* @__PURE__ */ jsxs16(
2466
+ ArkDialog.Root,
2467
+ {
2468
+ open,
2469
+ initialFocusEl: () => contentRef.current,
2470
+ onOpenChange: (details) => onOpenChange?.(details.open),
2471
+ children: [
2472
+ trigger && /* @__PURE__ */ jsx30(
2473
+ ArkDialog.Trigger,
2474
+ {
2475
+ asChild: triggerAsChild,
2476
+ className: triggerClassName,
2477
+ children: trigger
2478
+ }
2479
+ ),
2480
+ /* @__PURE__ */ jsxs16(Portal2, { children: [
2481
+ showBackdrop && /* @__PURE__ */ jsx30(
2482
+ ArkDialog.Backdrop,
2483
+ {
2484
+ className: cn(
2485
+ "polli:fixed polli:inset-0 polli:z-[100] polli:bg-ink-950/50",
2486
+ backdropClassName
2487
+ )
2488
+ }
2489
+ ),
2490
+ /* @__PURE__ */ jsx30(
2491
+ ArkDialog.Positioner,
2492
+ {
2493
+ "data-theme": theme,
2494
+ className: cn(
2495
+ "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",
2496
+ positionerClassName
2497
+ ),
2498
+ children: /* @__PURE__ */ jsxs16(
2499
+ ArkDialog.Content,
2500
+ {
2501
+ ref: contentRef,
2502
+ "data-theme": theme,
2503
+ "aria-label": ariaLabel,
2504
+ "aria-labelledby": labelledBy,
2505
+ className: cn(
2506
+ "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",
2507
+ sizeClasses2[size],
2508
+ contentClassName
2509
+ ),
2510
+ children: [
2511
+ title && /* @__PURE__ */ jsx30(
2512
+ DialogTitle,
2513
+ {
2514
+ className: cn(
2515
+ "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
2516
+ titleClassName
2517
+ ),
2518
+ children: title
2519
+ }
2520
+ ),
2521
+ children
2522
+ ]
2523
+ }
2524
+ )
2525
+ }
2526
+ )
2527
+ ] })
2528
+ ]
2529
+ }
2530
+ );
2531
+ };
2532
+ var DialogTitle = ArkDialog.Title;
2533
+
2534
+ // src/primitives/DropdownItem.tsx
2535
+ import { jsx as jsx31 } from "react/jsx-runtime";
2536
+ function DropdownItem({
2537
+ as,
2538
+ className,
2539
+ children,
2540
+ ...rest
2541
+ }) {
2542
+ const Component = as || "button";
2543
+ return /* @__PURE__ */ jsx31(
2544
+ Component,
2545
+ {
2546
+ ...Component === "button" ? { type: "button" } : void 0,
2547
+ ...rest,
2548
+ className: cn(
2549
+ "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",
2550
+ className
2551
+ ),
2552
+ children
2553
+ }
2554
+ );
2555
+ }
2556
+
2557
+ // src/primitives/Field.tsx
2558
+ import { Field } from "@ark-ui/react/field";
2559
+
2560
+ // src/primitives/InlineLink.tsx
2561
+ import { jsx as jsx32, jsxs as jsxs17 } from "react/jsx-runtime";
2562
+ function isExternalHref2(href) {
2563
+ return typeof href === "string" && /^https?:\/\//.test(href);
2564
+ }
2565
+ function InlineLink({
2566
+ as,
1526
2567
  theme,
1527
- id,
1528
- framed = false,
1529
- action,
1530
- actionClassName,
2568
+ external,
2569
+ showIcon = true,
2570
+ className,
1531
2571
  children,
1532
- className
1533
- }) => /* @__PURE__ */ jsxs10("section", { id, className: cn2("scroll-mt-10 space-y-2", className), children: [
1534
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center justify-between gap-3 px-1", children: [
1535
- /* @__PURE__ */ jsx21(
1536
- "h2",
1537
- {
1538
- "data-theme": theme,
1539
- className: "text-left text-lg font-semibold sm:text-xl text-theme-text-strong",
1540
- children: title
1541
- }
1542
- ),
1543
- action && /* @__PURE__ */ jsx21("div", { className: cn2("shrink-0", actionClassName), children: action })
1544
- ] }),
1545
- framed ? /* @__PURE__ */ jsx21(Surface, { variant: "panel", theme, children }) : children
1546
- ] });
2572
+ ...linkProps
2573
+ }) {
2574
+ const Component = as || "a";
2575
+ const isExternal = external ?? isExternalHref2(linkProps.href);
2576
+ return /* @__PURE__ */ jsxs17(
2577
+ Component,
2578
+ {
2579
+ "data-theme": theme,
2580
+ target: isExternal ? "_blank" : void 0,
2581
+ rel: isExternal ? "noopener noreferrer" : void 0,
2582
+ className: cn(
2583
+ "polli-control polli:inline-flex polli:items-center polli:gap-1 polli:rounded-sm polli:font-semibold polli:text-theme-text-strong",
2584
+ "polli:underline polli:decoration-theme-border polli:decoration-2 polli:underline-offset-3",
2585
+ "polli:transition-colors polli:hover:text-theme-text-soft polli:hover:decoration-theme-text-soft",
2586
+ className
2587
+ ),
2588
+ ...linkProps,
2589
+ children: [
2590
+ children,
2591
+ showIcon && isExternal && /* @__PURE__ */ jsx32(
2592
+ ExternalLinkIcon,
2593
+ {
2594
+ "aria-hidden": "true",
2595
+ className: "polli:h-3.5 polli:w-3.5 polli:shrink-0 polli:opacity-65"
2596
+ }
2597
+ )
2598
+ ]
2599
+ }
2600
+ );
2601
+ }
2602
+
2603
+ // src/primitives/Input.tsx
2604
+ import { forwardRef as forwardRef2 } from "react";
2605
+ import { jsx as jsx33 } from "react/jsx-runtime";
2606
+ var Input = forwardRef2(
2607
+ ({ className, error, hideNumberSteppers, ...props }, ref) => /* @__PURE__ */ jsx33(
2608
+ "input",
2609
+ {
2610
+ ref,
2611
+ "data-error": error ? "true" : void 0,
2612
+ className: cn(
2613
+ "polli-input polli:px-3 polli:py-2 polli:border polli:rounded-lg",
2614
+ "polli:text-ink-950",
2615
+ "polli:transition-colors",
2616
+ "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
2617
+ hideNumberSteppers && "polli-input-number-clean",
2618
+ className
2619
+ ),
2620
+ ...props
2621
+ }
2622
+ )
2623
+ );
1547
2624
 
1548
2625
  // src/primitives/Slider.tsx
1549
2626
  import { forwardRef as forwardRef3 } from "react";
1550
- import { jsx as jsx22 } from "react/jsx-runtime";
2627
+ import { jsx as jsx34 } from "react/jsx-runtime";
1551
2628
  var toNumber = (value) => {
1552
2629
  if (typeof value === "number") return value;
1553
2630
  if (typeof value !== "string" || value.trim() === "") return void 0;
@@ -1587,7 +2664,7 @@ var Slider = forwardRef3(
1587
2664
  ...style,
1588
2665
  ...progressPercent === void 0 ? null : { "--polli-slider-progress": `${progressPercent}%` }
1589
2666
  };
1590
- return /* @__PURE__ */ jsx22(
2667
+ return /* @__PURE__ */ jsx34(
1591
2668
  "input",
1592
2669
  {
1593
2670
  ref,
@@ -1597,63 +2674,19 @@ var Slider = forwardRef3(
1597
2674
  value,
1598
2675
  defaultValue,
1599
2676
  style: sliderStyle,
1600
- className: cn2("polli-slider", className),
2677
+ className: cn("polli-slider", className),
1601
2678
  ...props
1602
2679
  }
1603
2680
  );
1604
2681
  }
1605
2682
  );
1606
2683
 
1607
- // src/primitives/StatCard.tsx
1608
- import { jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
1609
- var StatCard = ({
1610
- label,
1611
- value,
1612
- detail,
1613
- theme,
1614
- className,
1615
- labelClassName,
1616
- valueClassName,
1617
- detailClassName
1618
- }) => /* @__PURE__ */ jsxs11("div", { "data-theme": theme, className: cn2("polli:text-sm", className), children: [
1619
- /* @__PURE__ */ jsx23(
1620
- "div",
1621
- {
1622
- className: cn2(
1623
- "polli:text-micro polli:font-bold polli:uppercase polli:tracking-wide polli:text-theme-text-strong",
1624
- labelClassName
1625
- ),
1626
- children: label
1627
- }
1628
- ),
1629
- /* @__PURE__ */ jsx23(
1630
- "div",
1631
- {
1632
- className: cn2(
1633
- "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",
1634
- valueClassName
1635
- ),
1636
- children: value
1637
- }
1638
- ),
1639
- detail && /* @__PURE__ */ jsx23(
1640
- "div",
1641
- {
1642
- className: cn2(
1643
- "polli:mt-2 polli:text-xs polli:text-theme-text-soft",
1644
- detailClassName
1645
- ),
1646
- children: detail
1647
- }
1648
- )
1649
- ] });
1650
-
1651
2684
  // src/primitives/Switch.tsx
1652
- import { jsx as jsx24 } from "react/jsx-runtime";
2685
+ import { jsx as jsx35 } from "react/jsx-runtime";
1653
2686
  var trackClasses = {
1654
- off: "polli:bg-gray-200",
1655
- on: "polli:bg-[oklch(0.88_0.12_158)]",
1656
- invalid: "polli:bg-[oklch(0.88_0.12_25)]"
2687
+ off: "polli:bg-ink-200",
2688
+ on: "polli:bg-intent-success-bg-light",
2689
+ invalid: "polli:bg-intent-danger-bg-light"
1657
2690
  };
1658
2691
  var Switch = ({
1659
2692
  checked,
@@ -1665,7 +2698,7 @@ var Switch = ({
1665
2698
  }) => {
1666
2699
  const effectiveStatus = status ?? (checked ? "on" : "off");
1667
2700
  const resolvedAriaLabel = ariaLabel ?? (checked ? "Turn off toggle" : "Turn on toggle");
1668
- return /* @__PURE__ */ jsx24(
2701
+ return /* @__PURE__ */ jsx35(
1669
2702
  "button",
1670
2703
  {
1671
2704
  type: "button",
@@ -1674,16 +2707,16 @@ var Switch = ({
1674
2707
  "aria-label": resolvedAriaLabel,
1675
2708
  onClick: () => onChange(!checked),
1676
2709
  disabled,
1677
- className: cn2(
1678
- "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",
2710
+ className: cn(
2711
+ "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",
1679
2712
  trackClasses[effectiveStatus],
1680
2713
  className
1681
2714
  ),
1682
- children: /* @__PURE__ */ jsx24(
2715
+ children: /* @__PURE__ */ jsx35(
1683
2716
  "span",
1684
2717
  {
1685
- className: cn2(
1686
- "polli:inline-block polli:h-5 polli:w-5 polli:rounded-full polli:bg-white polli:shadow-sm polli:transition-transform",
2718
+ className: cn(
2719
+ "polli:inline-block polli:h-5 polli:w-5 polli:rounded-full polli:bg-surface-opaque polli:shadow-sm polli:transition-transform",
1687
2720
  checked ? "polli:translate-x-6" : "polli:translate-x-1"
1688
2721
  )
1689
2722
  }
@@ -1693,7 +2726,7 @@ var Switch = ({
1693
2726
  };
1694
2727
 
1695
2728
  // src/primitives/Table.tsx
1696
- import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs12 } from "react/jsx-runtime";
2729
+ import { Fragment as Fragment5, jsx as jsx36, jsxs as jsxs18 } from "react/jsx-runtime";
1697
2730
  var alignClasses = {
1698
2731
  left: "polli:text-left",
1699
2732
  center: "polli:text-center",
@@ -1705,42 +2738,42 @@ var rowIntentClasses = {
1705
2738
  warning: "polli:bg-intent-warning-bg-light/65",
1706
2739
  danger: "polli:bg-intent-danger-bg-light/65"
1707
2740
  };
1708
- var Table = ({ className, ...rest }) => /* @__PURE__ */ jsx25(
2741
+ var Table = ({ className, ...rest }) => /* @__PURE__ */ jsx36(
1709
2742
  "table",
1710
2743
  {
1711
2744
  ...rest,
1712
- className: cn2(
2745
+ className: cn(
1713
2746
  "polli:w-full polli:border-collapse polli:text-sm",
1714
2747
  className
1715
2748
  )
1716
2749
  }
1717
2750
  );
1718
- var TableHead = ({ className, ...rest }) => /* @__PURE__ */ jsx25(
2751
+ var TableHead = ({ className, ...rest }) => /* @__PURE__ */ jsx36(
1719
2752
  "thead",
1720
2753
  {
1721
2754
  ...rest,
1722
- className: cn2(
1723
- "polli:bg-theme-bg-active polli:text-micro polli:text-theme-text-muted",
2755
+ className: cn(
2756
+ "polli:bg-transparent polli:text-micro polli:text-theme-text-muted",
1724
2757
  className
1725
2758
  )
1726
2759
  }
1727
2760
  );
1728
- var TableBody = ({ className, ...rest }) => /* @__PURE__ */ jsx25(
2761
+ var TableBody = ({ className, ...rest }) => /* @__PURE__ */ jsx36(
1729
2762
  "tbody",
1730
2763
  {
1731
2764
  ...rest,
1732
- className: cn2("polli:divide-y polli:divide-theme-border/65", className)
2765
+ className: cn("polli:divide-y polli:divide-theme-border/65", className)
1733
2766
  }
1734
2767
  );
1735
2768
  var TableRow = ({
1736
2769
  intent = "default",
1737
2770
  className,
1738
2771
  ...rest
1739
- }) => /* @__PURE__ */ jsx25(
2772
+ }) => /* @__PURE__ */ jsx36(
1740
2773
  "tr",
1741
2774
  {
1742
2775
  ...rest,
1743
- className: cn2(
2776
+ className: cn(
1744
2777
  "polli:transition-colors polli:hover:bg-theme-bg-subtle",
1745
2778
  rowIntentClasses[intent],
1746
2779
  className
@@ -1756,11 +2789,11 @@ var TableHeaderCell = ({
1756
2789
  children,
1757
2790
  ...rest
1758
2791
  }) => {
1759
- const content = /* @__PURE__ */ jsxs12(Fragment3, { children: [
1760
- /* @__PURE__ */ jsx25("span", { children }),
1761
- active && sortDirection && /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", children: sortDirection === "asc" ? "^" : "v" })
2792
+ const content = /* @__PURE__ */ jsxs18(Fragment5, { children: [
2793
+ /* @__PURE__ */ jsx36("span", { children }),
2794
+ active && sortDirection && /* @__PURE__ */ jsx36("span", { "aria-hidden": "true", children: sortDirection === "asc" ? "^" : "v" })
1762
2795
  ] });
1763
- const classes = cn2(
2796
+ const classes = cn(
1764
2797
  "polli:px-3 polli:py-2 polli:font-bold polli:uppercase polli:tracking-wide",
1765
2798
  alignClasses[align],
1766
2799
  active && "polli:text-theme-text-strong",
@@ -1768,15 +2801,15 @@ var TableHeaderCell = ({
1768
2801
  className
1769
2802
  );
1770
2803
  if (!onSort) {
1771
- return /* @__PURE__ */ jsx25("th", { ...rest, className: classes, children: content });
2804
+ return /* @__PURE__ */ jsx36("th", { ...rest, className: classes, children: content });
1772
2805
  }
1773
- return /* @__PURE__ */ jsx25("th", { ...rest, className: classes, children: /* @__PURE__ */ jsx25(
2806
+ return /* @__PURE__ */ jsx36("th", { ...rest, className: classes, children: /* @__PURE__ */ jsx36(
1774
2807
  "button",
1775
2808
  {
1776
2809
  type: "button",
1777
2810
  onClick: onSort,
1778
- className: cn2(
1779
- "polli:inline-flex polli:w-full polli:items-center polli:gap-1 polli:bg-transparent polli:p-0 polli:font-bold polli:text-inherit",
2811
+ className: cn(
2812
+ "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",
1780
2813
  align === "right" && "polli:justify-end",
1781
2814
  align === "center" && "polli:justify-center"
1782
2815
  ),
@@ -1790,11 +2823,11 @@ var TableCell = ({
1790
2823
  muted = false,
1791
2824
  className,
1792
2825
  ...rest
1793
- }) => /* @__PURE__ */ jsx25(
2826
+ }) => /* @__PURE__ */ jsx36(
1794
2827
  "td",
1795
2828
  {
1796
2829
  ...rest,
1797
- className: cn2(
2830
+ className: cn(
1798
2831
  "polli:px-3 polli:py-2 polli:align-middle",
1799
2832
  alignClasses[align],
1800
2833
  numeric && "polli:tabular-nums",
@@ -1804,18 +2837,60 @@ var TableCell = ({
1804
2837
  }
1805
2838
  );
1806
2839
 
2840
+ // src/primitives/Textarea.tsx
2841
+ import { forwardRef as forwardRef4 } from "react";
2842
+ import { jsx as jsx37 } from "react/jsx-runtime";
2843
+ var Textarea = forwardRef4(
2844
+ ({ className, error, rows = 4, ...props }, ref) => /* @__PURE__ */ jsx37(
2845
+ "textarea",
2846
+ {
2847
+ ref,
2848
+ rows,
2849
+ "data-error": error ? "true" : void 0,
2850
+ className: cn(
2851
+ "polli-textarea polli:w-full polli:rounded-lg polli:border polli:px-3 polli:py-2",
2852
+ "polli:min-h-20 polli:resize-y polli:font-body polli:text-base",
2853
+ "polli:text-ink-950",
2854
+ "polli:transition-colors",
2855
+ "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
2856
+ className
2857
+ ),
2858
+ ...props
2859
+ }
2860
+ )
2861
+ );
2862
+ Textarea.displayName = "Textarea";
2863
+
2864
+ // src/theme-palette.json
2865
+ var theme_palette_default = {
2866
+ bgPale: {
2867
+ amber: "#fef3c7",
2868
+ blue: "#dbeafe",
2869
+ pink: "#fce7f3",
2870
+ coral: "#ffedd5",
2871
+ teal: "#ccfbf1",
2872
+ violet: "#ede9fe",
2873
+ emerald: "#d1fae5"
2874
+ },
2875
+ brandDark: "#110518"
2876
+ };
2877
+
1807
2878
  // src/theme.ts
1808
2879
  var themes = [
1809
2880
  "amber",
1810
2881
  "blue",
1811
2882
  "pink",
2883
+ "coral",
1812
2884
  "teal",
1813
2885
  "violet",
1814
- "green"
2886
+ "emerald"
1815
2887
  ];
2888
+ var themePalette = theme_palette_default;
1816
2889
  export {
1817
2890
  Alert,
2891
+ AppHeader,
1818
2892
  AppIcon,
2893
+ AudioIcon,
1819
2894
  BeakerIcon,
1820
2895
  BookIcon,
1821
2896
  Button,
@@ -1825,6 +2900,7 @@ export {
1825
2900
  Chip,
1826
2901
  ClipboardIcon,
1827
2902
  ClockIcon,
2903
+ CodeBlock,
1828
2904
  Collapsible,
1829
2905
  CopyButton,
1830
2906
  Dialog,
@@ -1832,21 +2908,31 @@ export {
1832
2908
  DiscordIcon,
1833
2909
  DownloadIcon,
1834
2910
  Dropdown,
2911
+ DropdownItem,
1835
2912
  ExternalLinkButton,
1836
2913
  ExternalLinkIcon,
1837
2914
  Field,
2915
+ FileUpload,
1838
2916
  GenApiIcon,
1839
2917
  GitHubIcon,
2918
+ Heading,
1840
2919
  IconButton,
1841
2920
  ImageIcon,
1842
2921
  InfoTip,
2922
+ InlineLink,
1843
2923
  Input,
2924
+ LinkCard,
1844
2925
  LockIcon,
1845
2926
  MailIcon,
2927
+ Markdown,
1846
2928
  McpIcon,
2929
+ MediaPlaceholder,
1847
2930
  MenuIcon,
1848
2931
  MultiSelect,
2932
+ NavItem,
1849
2933
  PeriodPicker,
2934
+ PlusIcon,
2935
+ Prose,
1850
2936
  ScrollArea,
1851
2937
  Section,
1852
2938
  Slider,
@@ -1861,15 +2947,20 @@ export {
1861
2947
  TableHeaderCell,
1862
2948
  TableRow,
1863
2949
  TerminalIcon,
2950
+ Text,
2951
+ Textarea,
1864
2952
  TokensIcon,
1865
2953
  Tooltip,
1866
2954
  TrendUpIcon,
1867
2955
  WalletIcon,
1868
2956
  XIcon,
1869
- cn,
2957
+ cn2 as cn,
1870
2958
  currentPeriod,
1871
2959
  getPeriodBucketKeys,
2960
+ headingClassName,
1872
2961
  periodBucketKeyToDate,
2962
+ textClassName,
2963
+ themePalette,
1873
2964
  themes,
1874
2965
  useScrollLock
1875
2966
  };