@maxhealth.tech/prefab 0.3.22 → 0.3.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +8 -0
  3. package/dist/a2ui/catalog.d.ts.map +1 -1
  4. package/dist/a2ui/catalog.js +1 -10
  5. package/dist/a2ui/catalog.js.map +1 -1
  6. package/dist/a2ui/control.d.ts.map +1 -1
  7. package/dist/a2ui/control.js +1 -10
  8. package/dist/a2ui/control.js.map +1 -1
  9. package/dist/a2ui.min.js +1 -1
  10. package/dist/components/form/index.d.ts +2 -1
  11. package/dist/components/form/index.d.ts.map +1 -1
  12. package/dist/components/form/index.js +1 -1
  13. package/dist/components/form/index.js.map +1 -1
  14. package/dist/core/guards.d.ts +2 -0
  15. package/dist/core/guards.d.ts.map +1 -1
  16. package/dist/core/guards.js +13 -1
  17. package/dist/core/guards.js.map +1 -1
  18. package/dist/core/version.d.ts +1 -1
  19. package/dist/core/version.js +1 -1
  20. package/dist/prefab.css +668 -436
  21. package/dist/renderer/components/alert.js +0 -5
  22. package/dist/renderer/components/alert.js.map +1 -1
  23. package/dist/renderer/components/card.js +0 -2
  24. package/dist/renderer/components/card.js.map +1 -1
  25. package/dist/renderer/components/charts/cartesian.d.ts +2 -2
  26. package/dist/renderer/components/charts/cartesian.d.ts.map +1 -1
  27. package/dist/renderer/components/charts/cartesian.js +6 -7
  28. package/dist/renderer/components/charts/cartesian.js.map +1 -1
  29. package/dist/renderer/components/charts/helpers.d.ts +12 -2
  30. package/dist/renderer/components/charts/helpers.d.ts.map +1 -1
  31. package/dist/renderer/components/charts/helpers.js +47 -24
  32. package/dist/renderer/components/charts/helpers.js.map +1 -1
  33. package/dist/renderer/components/charts/index.d.ts.map +1 -1
  34. package/dist/renderer/components/charts/index.js +6 -5
  35. package/dist/renderer/components/charts/index.js.map +1 -1
  36. package/dist/renderer/components/charts/scatter.d.ts +2 -2
  37. package/dist/renderer/components/charts/scatter.d.ts.map +1 -1
  38. package/dist/renderer/components/charts/scatter.js +18 -18
  39. package/dist/renderer/components/charts/scatter.js.map +1 -1
  40. package/dist/renderer/components/choice.js +67 -39
  41. package/dist/renderer/components/choice.js.map +1 -1
  42. package/dist/renderer/components/data.js +40 -73
  43. package/dist/renderer/components/data.js.map +1 -1
  44. package/dist/renderer/components/form.d.ts +8 -10
  45. package/dist/renderer/components/form.d.ts.map +1 -1
  46. package/dist/renderer/components/form.js +144 -238
  47. package/dist/renderer/components/form.js.map +1 -1
  48. package/dist/renderer/components/interactive.d.ts.map +1 -1
  49. package/dist/renderer/components/interactive.js +115 -158
  50. package/dist/renderer/components/interactive.js.map +1 -1
  51. package/dist/renderer/components/layout.js +1 -7
  52. package/dist/renderer/components/layout.js.map +1 -1
  53. package/dist/renderer/components/media.d.ts.map +1 -1
  54. package/dist/renderer/components/media.js +1 -7
  55. package/dist/renderer/components/media.js.map +1 -1
  56. package/dist/renderer/components/table.d.ts +4 -0
  57. package/dist/renderer/components/table.d.ts.map +1 -1
  58. package/dist/renderer/components/table.js +47 -35
  59. package/dist/renderer/components/table.js.map +1 -1
  60. package/dist/renderer/index.js +7 -12
  61. package/dist/renderer/index.js.map +1 -1
  62. package/dist/renderer/theme.d.ts.map +1 -1
  63. package/dist/renderer/theme.js +3 -32
  64. package/dist/renderer/theme.js.map +1 -1
  65. package/dist/renderer.auto.min.js +10 -10
  66. package/dist/renderer.min.js +10 -10
  67. package/package.json +1 -1
package/dist/prefab.css CHANGED
@@ -1,31 +1,12 @@
1
- /*
2
- * prefab.css — Base theme for the prefab renderer.
3
- *
4
- * Provides CSS custom properties (shadcn-compatible design tokens) and
5
- * structural styles for all pf-* component classes. Import this file or
6
- * add a <link> tag to get a polished default look without BYO CSS.
7
- *
8
- * Token naming follows shadcn/ui conventions so existing Tailwind themes
9
- * can override them seamlessly.
10
- */
11
-
12
- /* ═══════════════════════════════════════════════════════════════════════════
13
- 1. DESIGN TOKENS — Light & Dark
14
- ═══════════════════════════════════════════════════════════════════════════
15
- Fallback chain: MCP Apps vars → VS Code vars → static defaults.
16
- When rendered inside Claude Desktop, VS Code webviews, or standalone,
17
- the correct tokens are resolved automatically without user CSS.
18
-
19
- MCP Apps spec: --color-background-primary, --color-text-primary, …
20
- VS Code: --vscode-editor-background, --vscode-editor-foreground, …
21
- ═══════════════════════════════════════════════════════════════════════════ */
1
+ /* prefab.css: shadcn-compatible tokens and pf-* component styles. Built into dist/prefab.css. */
22
2
 
23
3
  :root {
24
- /* Radii */
4
+ color-scheme: light;
5
+
25
6
  --radius: var(--border-radius-md, 8px);
26
7
  --radius-sm: var(--border-radius-sm, 6px);
8
+ --radius-lg: var(--border-radius-lg, 12px);
27
9
 
28
- /* Core palette — MCP Apps → VS Code → static */
29
10
  --background: var(--color-background-primary, var(--vscode-editor-background, #ffffff));
30
11
  --foreground: var(--color-text-primary, var(--vscode-editor-foreground, #09090b));
31
12
 
@@ -50,24 +31,24 @@
50
31
  --destructive: var(--color-background-danger, var(--vscode-errorForeground, #ef4444));
51
32
  --destructive-foreground: var(--color-text-inverse, #ffffff);
52
33
 
53
- --success: var(--color-background-success, #22c55e);
34
+ --success: var(--color-background-success, #16a34a);
54
35
  --success-foreground: var(--color-text-inverse, #ffffff);
55
36
 
56
37
  --warning: var(--color-background-warning, #f59e0b);
57
- --warning-foreground: var(--color-text-inverse, #ffffff);
38
+ --warning-foreground: var(--color-text-inverse, #422006);
39
+
40
+ --info: var(--color-text-info, #0284c7);
41
+ --info-foreground: var(--color-text-inverse, #ffffff);
58
42
 
59
43
  --border: var(--color-border-primary, var(--vscode-panel-border, #e5e7eb));
60
44
  --input: var(--color-border-secondary, var(--vscode-input-background, #e5e7eb));
61
45
  --ring: var(--color-ring-primary, var(--vscode-focusBorder, #3b82f6));
62
46
 
63
- /* Typography — MCP Apps uses --font-sans/--font-mono directly (same names);
64
- host inline styles override these automatically. VS Code fallback here. */
65
47
  --font-sans: var(--vscode-font-family, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
66
48
  Roboto, "Helvetica Neue", Arial, sans-serif);
67
49
  --font-mono: var(--vscode-editor-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
68
50
  "Liberation Mono", "Courier New", monospace);
69
51
 
70
- /* Shadows — MCP Apps host overrides these names inline when present */
71
52
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
72
53
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
73
54
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
@@ -75,6 +56,8 @@
75
56
 
76
57
  @media (prefers-color-scheme: dark) {
77
58
  :root:not([data-theme="light"]) {
59
+ color-scheme: dark;
60
+
78
61
  --background: var(--color-background-primary, var(--vscode-editor-background, #09090b));
79
62
  --foreground: var(--color-text-primary, var(--vscode-editor-foreground, #fafafa));
80
63
 
@@ -105,30 +88,22 @@
105
88
  --warning: var(--color-background-warning, #fbbf24);
106
89
  --warning-foreground: var(--color-text-inverse, #09090b);
107
90
 
91
+ --info: var(--color-text-info, #38bdf8);
92
+ --info-foreground: var(--color-text-inverse, #09090b);
93
+
108
94
  --border: var(--color-border-primary, var(--vscode-panel-border, #27272a));
109
95
  --input: var(--color-border-secondary, var(--vscode-input-background, #27272a));
110
96
  --ring: var(--color-ring-primary, var(--vscode-focusBorder, #60a5fa));
111
97
  }
112
98
  }
113
99
 
114
- /* Explicit dark override, via the data-theme attribute or the dark class.
115
- Static values only — NO host var references.
116
- In hosted mode (Claude/VS Code), data-theme is never set; the host's inline
117
- vars resolve through the var() chain in :root / @media-dark above.
118
-
119
- Three selectors, matching what compileThemeCss() emits for a wire theme, so
120
- the base tokens and the theme's tokens always flip on the same element:
121
- - :root[...] keeps specificity (0,2,0) to beat the @media dark :root:not(...)
122
- rule, which it ties with and wins on document order.
123
- - the bare attribute and class selectors carry (0,1,0) and match at ANY depth,
124
- which is what setThemeAttrs needs: it themes the prefab mount container, and
125
- createThemeToggle({ syncDocument: false }) themes ONLY that container.
126
- Specificity is not a concern below the root, since every other token rule
127
- here is :root-scoped and so does not match a container at all — a
128
- declaration on the element always beats what it would otherwise inherit. */
100
+ /* Explicit schemes via data-theme or the dark/light class. Static values only, so
101
+ the bare selectors also theme a nested mount container at any depth. */
129
102
  :root[data-theme="dark"],
130
103
  [data-theme="dark"],
131
104
  .dark {
105
+ color-scheme: dark;
106
+
132
107
  --background: #09090b;
133
108
  --foreground: #fafafa;
134
109
 
@@ -159,17 +134,19 @@
159
134
  --warning: #fbbf24;
160
135
  --warning-foreground: #09090b;
161
136
 
137
+ --info: #38bdf8;
138
+ --info-foreground: #09090b;
139
+
162
140
  --border: #27272a;
163
141
  --input: #27272a;
164
142
  --ring: #60a5fa;
165
143
  }
166
144
 
167
- /* Explicit light override, via the data-theme attribute or the light class.
168
- Same specificity, depth and static-value strategy as the dark block above.
169
- This is the direction that makes a light island under a dark root work. */
170
145
  :root[data-theme="light"],
171
146
  [data-theme="light"],
172
147
  .light {
148
+ color-scheme: light;
149
+
173
150
  --background: #ffffff;
174
151
  --foreground: #09090b;
175
152
 
@@ -194,37 +171,56 @@
194
171
  --destructive: #ef4444;
195
172
  --destructive-foreground: #ffffff;
196
173
 
197
- --success: #22c55e;
174
+ --success: #16a34a;
198
175
  --success-foreground: #ffffff;
199
176
 
200
177
  --warning: #f59e0b;
201
- --warning-foreground: #ffffff;
178
+ --warning-foreground: #422006;
179
+
180
+ --info: #0284c7;
181
+ --info-foreground: #ffffff;
202
182
 
203
183
  --border: #e5e7eb;
204
184
  --input: #e5e7eb;
205
185
  --ring: #3b82f6;
206
186
  }
207
187
 
208
- /* ═══════════════════════════════════════════════════════════════════════════
209
- 2. RESET & BASE
210
- ═══════════════════════════════════════════════════════════════════════════ */
211
-
212
188
  *, *::before, *::after {
213
189
  box-sizing: border-box;
214
190
  }
215
191
 
216
192
  .pf-app-root {
217
193
  font-family: var(--font-sans);
194
+ font-size: 1rem;
218
195
  color: var(--foreground);
219
196
  background-color: var(--background);
220
197
  line-height: 1.5;
221
198
  -webkit-font-smoothing: antialiased;
222
199
  -moz-osx-font-smoothing: grayscale;
200
+ text-rendering: optimizeLegibility;
201
+ }
202
+
203
+ :where(.pf-button, .pf-input, .pf-textarea, .pf-select, .pf-combobox-input, .pf-datatable-search,
204
+ .pf-tab-trigger, .pf-accordion-trigger, .pf-carousel-prev, .pf-carousel-next, .pf-dialog-close,
205
+ .pf-theme-toggle, .pf-expandable-row-summary) {
206
+ font: inherit;
207
+ color: inherit;
208
+ letter-spacing: inherit;
223
209
  }
224
210
 
225
- /* ═══════════════════════════════════════════════════════════════════════════
226
- 3. LAYOUT
227
- ═══════════════════════════════════════════════════════════════════════════ */
211
+ :where(.pf-app-root, .pf-toast-region, .pf-dialog) :focus-visible {
212
+ outline: 2px solid var(--ring);
213
+ outline-offset: 2px;
214
+ }
215
+
216
+ @media (prefers-reduced-motion: reduce) {
217
+ :where(.pf-app-root, .pf-toast-region) *,
218
+ :where(.pf-app-root, .pf-toast-region) *::before,
219
+ :where(.pf-app-root, .pf-toast-region) *::after {
220
+ animation-duration: 0.01ms !important;
221
+ transition-duration: 0.01ms !important;
222
+ }
223
+ }
228
224
 
229
225
  .pf-column { display: flex; flex-direction: column; }
230
226
  .pf-row { display: flex; flex-direction: row; flex-wrap: wrap; }
@@ -236,27 +232,35 @@
236
232
  .pf-span { display: inline; }
237
233
  .pf-pages { position: relative; }
238
234
 
239
- /* ═══════════════════════════════════════════════════════════════════════════
240
- 4. TYPOGRAPHY
241
- ═══════════════════════════════════════════════════════════════════════════ */
235
+ .pf-master-detail { display: flex; flex-direction: row; min-height: 0; }
236
+ .pf-master-detail-master { flex-shrink: 0; overflow: auto; }
237
+ .pf-master-detail-detail { flex: 1; min-width: 0; overflow: auto; }
238
+
239
+ @media (max-width: 560px) {
240
+ .pf-grid { grid-template-columns: minmax(0, 1fr) !important; }
241
+ .pf-grid-item { grid-column: auto !important; }
242
+ .pf-master-detail { flex-direction: column; }
243
+ .pf-master-detail-master { width: auto !important; }
244
+ }
242
245
 
243
- .pf-heading { margin: 0; font-weight: 600; letter-spacing: -0.02em; }
244
- .pf-h1 { font-size: 2.25rem; line-height: 2.5rem; }
246
+ .pf-heading { margin: 0; font-weight: 600; letter-spacing: -0.02em; text-wrap: balance; }
247
+ .pf-h1 { font-size: 2.25rem; line-height: 2.5rem; font-weight: 700; }
245
248
  .pf-h2 { font-size: 1.875rem; line-height: 2.25rem; }
246
249
  .pf-h3 { font-size: 1.5rem; line-height: 2rem; }
247
250
  .pf-h4 { font-size: 1.25rem; line-height: 1.75rem; }
251
+ .pf-h5 { font-size: 1.125rem; line-height: 1.75rem; }
252
+ .pf-h6 { font-size: 1rem; line-height: 1.5rem; }
248
253
 
249
- .pf-text { }
250
- .pf-p { margin: 0; }
251
- .pf-lead { font-size: 1.25rem; color: var(--muted-foreground); }
252
- .pf-large { font-size: 1.125rem; font-weight: 600; }
253
- .pf-small { font-size: 0.875rem; }
254
- .pf-muted { color: var(--muted-foreground); font-size: 0.875rem; margin: 0; }
254
+ .pf-p { margin: 0; line-height: 1.625; }
255
+ .pf-lead { margin: 0; font-size: 1.125rem; line-height: 1.75rem; color: var(--muted-foreground); }
256
+ .pf-large { font-size: 1.125rem; line-height: 1.75rem; font-weight: 600; }
257
+ .pf-small { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; }
258
+ .pf-muted { margin: 0; color: var(--muted-foreground); font-size: 0.875rem; line-height: 1.25rem; }
255
259
 
256
260
  .pf-blockquote {
257
261
  margin: 0;
258
262
  padding-left: 1rem;
259
- border-left: 3px solid var(--border);
263
+ border-left: 2px solid var(--border);
260
264
  font-style: italic;
261
265
  color: var(--muted-foreground);
262
266
  }
@@ -264,31 +268,40 @@
264
268
  .pf-label {
265
269
  font-size: 0.875rem;
266
270
  font-weight: 500;
271
+ line-height: 1.25rem;
267
272
  }
268
273
 
269
274
  .pf-link {
270
275
  color: var(--primary);
271
276
  text-decoration: underline;
277
+ text-decoration-color: color-mix(in oklab, var(--primary) 40%, transparent);
272
278
  text-underline-offset: 4px;
273
279
  cursor: pointer;
280
+ transition: text-decoration-color 0.15s;
274
281
  }
275
- .pf-link:hover { text-decoration-thickness: 2px; }
282
+ .pf-link:hover { text-decoration-color: currentColor; }
276
283
 
277
284
  .pf-code {
278
285
  font-family: var(--font-mono);
279
- font-size: 0.875rem;
286
+ font-size: 0.8125rem;
287
+ line-height: 1.6;
280
288
  background: var(--muted);
281
289
  border: 1px solid var(--border);
282
290
  border-radius: var(--radius-sm);
283
- padding: 1rem;
291
+ padding: 0.875rem 1rem;
284
292
  overflow-x: auto;
285
293
  margin: 0;
286
294
  white-space: pre;
287
295
  }
288
296
 
289
297
  .pf-markdown { line-height: 1.7; }
290
- .pf-markdown h1, .pf-markdown h2, .pf-markdown h3 { margin-top: 1.5em; margin-bottom: 0.5em; }
298
+ .pf-markdown > :first-child { margin-top: 0; }
299
+ .pf-markdown > :last-child { margin-bottom: 0; }
300
+ .pf-markdown h1, .pf-markdown h2, .pf-markdown h3 { margin: 1.5em 0 0.5em; line-height: 1.3; letter-spacing: -0.01em; }
291
301
  .pf-markdown p { margin: 0.75em 0; }
302
+ .pf-markdown ul, .pf-markdown ol { margin: 0.75em 0; padding-left: 1.5em; }
303
+ .pf-markdown li + li { margin-top: 0.25em; }
304
+ .pf-markdown a { color: var(--primary); text-underline-offset: 4px; }
292
305
  .pf-markdown code {
293
306
  font-family: var(--font-mono);
294
307
  font-size: 0.875em;
@@ -296,6 +309,13 @@
296
309
  padding: 0.15em 0.4em;
297
310
  border-radius: 4px;
298
311
  }
312
+ .pf-markdown pre {
313
+ background: var(--muted);
314
+ border: 1px solid var(--border);
315
+ border-radius: var(--radius-sm);
316
+ padding: 0.875rem 1rem;
317
+ overflow-x: auto;
318
+ }
299
319
  .pf-markdown pre code { background: none; padding: 0; }
300
320
 
301
321
  .pf-kbd {
@@ -304,72 +324,88 @@
304
324
  justify-content: center;
305
325
  font-family: var(--font-mono);
306
326
  font-size: 0.75rem;
327
+ font-weight: 500;
328
+ line-height: 1;
307
329
  min-width: 1.5em;
308
- padding: 0.15em 0.4em;
330
+ height: 1.5em;
331
+ padding: 0 0.4em;
309
332
  border: 1px solid var(--border);
310
333
  border-radius: 4px;
311
334
  background: var(--muted);
335
+ color: var(--muted-foreground);
312
336
  box-shadow: 0 1px 0 var(--border);
313
337
  }
314
338
 
315
- /* ═══════════════════════════════════════════════════════════════════════════
316
- 5. CARD
317
- ═══════════════════════════════════════════════════════════════════════════ */
339
+ .pf-app-root [role="button"]:not(button, .pf-expandable-row-summary) { cursor: pointer; }
318
340
 
319
341
  .pf-card {
320
342
  background: var(--card);
321
343
  color: var(--card-foreground);
322
344
  border: 1px solid var(--border);
323
- border-radius: var(--radius);
324
- overflow: hidden;
345
+ border-radius: var(--radius-lg);
346
+ box-shadow: var(--shadow-sm);
325
347
  }
348
+ .pf-card:not(:has(> .pf-card-header, > .pf-card-content, > .pf-card-footer)) { padding: 1.5rem; }
326
349
 
327
- .pf-card-header { padding: 1.5rem 1.5rem 0; }
328
- .pf-card-content { padding: 1.5rem; }
329
- .pf-card-footer { padding: 0 1.5rem 1.5rem; display: flex; align-items: center; gap: 0.5rem; }
350
+ .pf-card[role="button"] { transition: border-color 0.15s, box-shadow 0.15s; }
351
+ .pf-card[role="button"]:hover { border-color: color-mix(in oklab, var(--primary) 35%, var(--border)); box-shadow: var(--shadow-md); }
330
352
 
331
- .pf-card-title { margin: 0; font-size: 1.25rem; font-weight: 600; }
332
- .pf-card-description { margin: 0.25rem 0 0; color: var(--muted-foreground); font-size: 0.875rem; }
353
+ .pf-card-header { display: flex; flex-direction: column; gap: 0.375rem; padding: 1.5rem 1.5rem 0; }
354
+ .pf-card-content { padding: 1.5rem; }
355
+ .pf-card-header + .pf-card-content { padding-top: 1.25rem; }
356
+ .pf-card-footer { display: flex; align-items: center; gap: 0.5rem; padding: 0 1.5rem 1.5rem; }
357
+ .pf-card-header:last-child { padding-bottom: 1.5rem; }
333
358
 
334
- /* ═══════════════════════════════════════════════════════════════════════════
335
- 6. ALERT
336
- ═══════════════════════════════════════════════════════════════════════════ */
359
+ .pf-card-title { margin: 0; font-size: 1.125rem; line-height: 1.4; font-weight: 600; letter-spacing: -0.01em; }
360
+ .pf-card-description { margin: 0; color: var(--muted-foreground); font-size: 0.875rem; line-height: 1.25rem; }
337
361
 
338
362
  .pf-alert {
363
+ --pf-tone: var(--foreground);
339
364
  position: relative;
340
- padding: 1rem 1rem 1rem 3rem;
365
+ display: flex;
366
+ flex-direction: column;
367
+ gap: 0.25rem;
368
+ padding: 0.875rem 1rem;
341
369
  border: 1px solid var(--border);
342
370
  border-radius: var(--radius);
371
+ background: var(--card);
372
+ color: var(--card-foreground);
373
+ font-size: 0.875rem;
374
+ line-height: 1.25rem;
343
375
  }
344
- .pf-alert[data-variant="destructive"] {
345
- border-color: var(--destructive);
346
- color: var(--destructive);
376
+ .pf-alert:has(> .pf-alert-icon) { padding-left: 2.75rem; }
377
+ .pf-alert[data-variant="destructive"] { --pf-tone: var(--destructive); }
378
+ .pf-alert[data-variant="success"] { --pf-tone: var(--success); }
379
+ .pf-alert[data-variant="warning"] { --pf-tone: var(--warning); }
380
+ .pf-alert[data-variant="info"] { --pf-tone: var(--info); }
381
+ .pf-alert:not([data-variant="default"]) {
382
+ border-color: color-mix(in oklab, var(--pf-tone) 45%, var(--border));
383
+ background: color-mix(in oklab, var(--pf-tone) 7%, var(--card));
384
+ color: color-mix(in oklab, var(--pf-tone) 70%, var(--foreground));
347
385
  }
348
386
  .pf-alert-icon {
349
387
  position: absolute;
350
388
  left: 1rem;
351
- top: 1rem;
389
+ top: 0.9375rem;
390
+ width: 1.125rem;
391
+ height: 1.125rem;
392
+ color: var(--pf-tone);
352
393
  }
353
- .pf-alert-title { margin: 0; font-weight: 600; font-size: 0.875rem; }
354
- .pf-alert-description { margin: 0.25rem 0 0; font-size: 0.875rem; }
355
-
356
- /* ═══════════════════════════════════════════════════════════════════════════
357
- 7. BADGE
358
- ═══════════════════════════════════════════════════════════════════════════ */
394
+ .pf-alert-title { margin: 0; font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; }
395
+ .pf-alert-description { margin: 0; font-size: 0.875rem; line-height: 1.25rem; opacity: 0.9; }
396
+ .pf-alert[data-variant="default"] .pf-alert-description { color: var(--muted-foreground); opacity: 1; }
359
397
 
360
398
  .pf-badge {
361
399
  display: inline-flex;
362
400
  align-items: center;
363
- /* Hug content: as a flex child, inline-flex is blockified to flex and would
364
- otherwise stretch to the container's cross size (full width in a column,
365
- full height in a row). align-self keeps the pill intrinsically sized; an
366
- explicit w-full/width utility still overrides it. */
367
401
  align-self: flex-start;
402
+ gap: 0.25rem;
403
+ border: 1px solid transparent;
368
404
  border-radius: 9999px;
369
- padding: 0.15em 0.6em;
405
+ padding: 0.125rem 0.5rem;
370
406
  font-size: 0.75rem;
371
- font-weight: 600;
372
- line-height: 1;
407
+ font-weight: 500;
408
+ line-height: 1rem;
373
409
  white-space: nowrap;
374
410
  transition: background-color 0.15s;
375
411
  }
@@ -378,27 +414,104 @@
378
414
  .pf-badge[data-variant="destructive"] { background: var(--destructive); color: var(--destructive-foreground); }
379
415
  .pf-badge[data-variant="success"] { background: var(--success); color: var(--success-foreground); }
380
416
  .pf-badge[data-variant="warning"] { background: var(--warning); color: var(--warning-foreground); }
381
- .pf-badge[data-variant="outline"] { background: transparent; border: 1px solid var(--border); color: var(--foreground); }
417
+ .pf-badge[data-variant="info"] { background: var(--info); color: var(--info-foreground); }
418
+ .pf-badge[data-variant="outline"] { background: transparent; border-color: var(--border); color: var(--foreground); }
382
419
 
383
420
  .pf-dot {
384
421
  display: inline-block;
422
+ flex-shrink: 0;
385
423
  width: 0.5rem;
386
424
  height: 0.5rem;
387
425
  border-radius: 9999px;
426
+ background-color: var(--muted-foreground);
388
427
  }
389
428
 
390
- /* ═══════════════════════════════════════════════════════════════════════════
391
- 8. DATA — Metric, Ring, Progress, Separator, Loader, Icon, Sparkline
392
- ═══════════════════════════════════════════════════════════════════════════ */
393
-
394
- .pf-metric { display: flex; flex-direction: column; gap: 0.25rem; }
395
- .pf-metric-label { font-size: 0.875rem; color: var(--muted-foreground); }
396
- .pf-metric-value { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }
397
- .pf-metric-delta { font-size: 0.875rem; font-weight: 500; margin-left: 0.5rem; }
398
- .pf-metric-desc { font-size: 0.75rem; color: var(--muted-foreground); }
429
+ .pf-toast-region {
430
+ position: fixed;
431
+ right: 1rem;
432
+ bottom: 1rem;
433
+ z-index: 9999;
434
+ display: flex;
435
+ flex-direction: column;
436
+ gap: 0.5rem;
437
+ width: min(24rem, calc(100vw - 2rem));
438
+ font-family: var(--font-sans);
439
+ color: var(--foreground);
440
+ line-height: 1.5;
441
+ pointer-events: none;
442
+ }
443
+ .pf-toast {
444
+ --pf-tone: var(--border);
445
+ display: flex;
446
+ flex-direction: column;
447
+ gap: 0.125rem;
448
+ background: var(--popover);
449
+ color: var(--popover-foreground);
450
+ border: 1px solid var(--border);
451
+ border-left: 3px solid var(--pf-tone);
452
+ border-radius: var(--radius);
453
+ padding: 0.75rem 1rem;
454
+ box-shadow: var(--shadow-lg);
455
+ pointer-events: auto;
456
+ animation: pf-toast-in 0.2s ease-out;
457
+ transition: opacity 0.3s ease, transform 0.3s ease;
458
+ }
459
+ .pf-toast--success { --pf-tone: var(--success); }
460
+ .pf-toast--error { --pf-tone: var(--destructive); }
461
+ .pf-toast--warning { --pf-tone: var(--warning); }
462
+ .pf-toast--info { --pf-tone: var(--info); }
463
+ .pf-toast--leaving { opacity: 0; transform: translateY(0.5rem); }
464
+ .pf-toast-title { font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; }
465
+ .pf-toast-description { font-size: 0.8125rem; line-height: 1.25rem; color: var(--muted-foreground); }
466
+ @keyframes pf-toast-in { from { opacity: 0; transform: translateY(0.5rem); } }
467
+
468
+ .pf-theme-toggle {
469
+ position: absolute;
470
+ z-index: 100;
471
+ display: flex;
472
+ align-items: center;
473
+ justify-content: center;
474
+ width: 2rem;
475
+ height: 2rem;
476
+ padding: 0;
477
+ border: 1px solid var(--border);
478
+ border-radius: var(--radius-sm);
479
+ background: var(--card);
480
+ color: var(--muted-foreground);
481
+ cursor: pointer;
482
+ backdrop-filter: blur(4px);
483
+ transition: color 0.15s, background-color 0.15s;
484
+ }
485
+ .pf-theme-toggle:hover { color: var(--foreground); background: var(--muted); }
486
+ .pf-theme-toggle[data-position="top-right"] { top: 0.25rem; right: 0.25rem; }
487
+ .pf-theme-toggle[data-position="top-left"] { top: 0.25rem; left: 0.25rem; }
488
+ .pf-theme-toggle[data-position="bottom-right"] { bottom: 0.25rem; right: 0.25rem; }
489
+ .pf-theme-toggle[data-position="bottom-left"] { bottom: 0.25rem; left: 0.25rem; }
490
+ .pf-app-root:has(> .pf-theme-toggle[data-position^="top"]) { padding-top: 2.75rem; }
491
+ .pf-app-root:has(> .pf-theme-toggle[data-position^="bottom"]) { padding-bottom: 2.75rem; }
492
+
493
+ .pf-metric { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
494
+ .pf-metric-label { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; color: var(--muted-foreground); }
495
+ .pf-metric-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; }
496
+ .pf-metric-value { font-size: 1.75rem; line-height: 2.25rem; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
497
+ .pf-metric-delta {
498
+ display: inline-flex;
499
+ align-items: center;
500
+ gap: 0.125rem;
501
+ font-size: 0.8125rem;
502
+ font-weight: 500;
503
+ font-variant-numeric: tabular-nums;
504
+ color: var(--muted-foreground);
505
+ }
506
+ .pf-metric-delta[data-sentiment="positive"] { color: color-mix(in oklab, var(--success) 80%, var(--foreground)); }
507
+ .pf-metric-delta[data-sentiment="negative"] { color: color-mix(in oklab, var(--destructive) 85%, var(--foreground)); }
508
+ .pf-metric-desc { font-size: 0.75rem; line-height: 1rem; color: var(--muted-foreground); }
399
509
 
400
- .pf-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
401
- .pf-ring-label { position: absolute; text-align: center; font-size: 0.875rem; font-weight: 600; }
510
+ .pf-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
511
+ .pf-ring svg { display: block; }
512
+ .pf-ring-track { stroke: var(--muted); }
513
+ .pf-ring-fill { stroke: var(--primary); transform: rotate(-90deg); transform-origin: center; transition: stroke-dashoffset 0.4s ease; }
514
+ .pf-ring-label { position: absolute; text-align: center; font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums; }
402
515
 
403
516
  .pf-progress {
404
517
  width: 100%;
@@ -415,300 +528,433 @@
415
528
  }
416
529
 
417
530
  .pf-separator {
418
- border: none;
419
- border-top: 1px solid var(--border);
531
+ flex-shrink: 0;
532
+ width: 100%;
533
+ height: 0;
420
534
  margin: 0;
535
+ border: 0;
536
+ border-top: 1px solid var(--border);
537
+ }
538
+
539
+ .pf-separator[data-orientation="vertical"] {
540
+ width: 0;
541
+ height: auto;
542
+ align-self: stretch;
543
+ border-top: 0;
544
+ border-left: 1px solid var(--border);
421
545
  }
422
546
 
423
547
  .pf-loader {
424
548
  display: inline-block;
549
+ flex-shrink: 0;
550
+ align-self: center;
425
551
  width: 1.5rem;
426
552
  height: 1.5rem;
427
553
  border: 2px solid var(--muted);
428
554
  border-top-color: var(--primary);
429
555
  border-radius: 50%;
430
- animation: pf-spin 0.6s linear infinite;
556
+ animation: pf-spin 0.7s linear infinite;
431
557
  }
432
558
  @keyframes pf-spin { to { transform: rotate(360deg); } }
433
559
 
434
- .pf-icon { display: inline-flex; align-items: center; }
435
-
436
- .pf-sparkline svg { display: block; }
560
+ .pf-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 1.25em; height: 1.25em; vertical-align: -0.25em; }
561
+ .pf-icon svg { width: 100%; height: 100%; }
437
562
 
438
- /* ═══════════════════════════════════════════════════════════════════════════
439
- 9. DATATABLE
440
- ═══════════════════════════════════════════════════════════════════════════ */
563
+ .pf-sparkline { display: inline-flex; flex-shrink: 0; }
564
+ .pf-sparkline svg { display: block; overflow: visible; }
565
+ .pf-sparkline polyline { stroke: var(--primary); stroke-linecap: round; stroke-linejoin: round; }
441
566
 
442
- .pf-datatable-wrapper { overflow-x: auto; }
567
+ .pf-datatable-wrapper { display: flex; flex-direction: column; gap: 0.75rem; min-width: 0; }
568
+ .pf-datatable-scroll {
569
+ overflow-x: auto;
570
+ border: 1px solid var(--border);
571
+ border-radius: var(--radius);
572
+ }
443
573
 
444
- .pf-datatable {
574
+ .pf-datatable, .pf-table {
445
575
  width: 100%;
446
576
  border-collapse: collapse;
447
577
  font-size: 0.875rem;
578
+ line-height: 1.25rem;
448
579
  }
449
- .pf-datatable-th {
580
+ .pf-datatable-th, .pf-table-header {
581
+ height: 2.5rem;
582
+ padding: 0 0.75rem;
450
583
  text-align: left;
451
- padding: 0.75rem 1rem;
452
- font-weight: 600;
453
- border-bottom: 2px solid var(--border);
584
+ vertical-align: middle;
585
+ font-size: 0.8125rem;
586
+ font-weight: 500;
587
+ color: var(--muted-foreground);
588
+ border-bottom: 1px solid var(--border);
454
589
  white-space: nowrap;
455
590
  }
456
- .pf-datatable-td {
457
- padding: 0.75rem 1rem;
591
+ .pf-datatable-th { background: color-mix(in oklab, var(--muted) 45%, transparent); }
592
+ .pf-datatable-td, .pf-table-cell {
593
+ padding: 0.75rem;
594
+ vertical-align: middle;
458
595
  border-bottom: 1px solid var(--border);
459
596
  }
460
- .pf-datatable-search {
461
- width: 100%;
462
- max-width: 20rem;
463
- padding: 0.5rem 0.75rem;
464
- margin-bottom: 0.75rem;
465
- border: 1px solid var(--input);
466
- border-radius: var(--radius-sm);
467
- font-size: 0.875rem;
468
- background: var(--background);
469
- color: var(--foreground);
470
- }
471
- .pf-datatable-search:focus {
472
- outline: 2px solid var(--ring);
473
- outline-offset: -1px;
474
- }
597
+ .pf-datatable tbody tr:last-child .pf-datatable-td { border-bottom: 0; }
598
+ .pf-datatable-row, .pf-table tbody .pf-table-row { transition: background-color 0.15s; }
599
+ .pf-datatable-row:hover, .pf-table tbody .pf-table-row:hover { background: color-mix(in oklab, var(--muted) 50%, transparent); }
600
+ .pf-datatable-row-clickable { cursor: pointer; }
601
+ .pf-datatable-row-selected,
602
+ .pf-datatable-row-selected:hover { background: color-mix(in oklab, var(--primary) 12%, transparent); }
603
+ .pf-datatable-empty { padding: 1.5rem 0.75rem; text-align: center; color: var(--muted-foreground); }
475
604
 
476
- /* ═══════════════════════════════════════════════════════════════════════════
477
- 10. TABLE (semantic HTML table)
478
- ═══════════════════════════════════════════════════════════════════════════ */
479
-
480
- .pf-table {
481
- width: 100%;
482
- border-collapse: collapse;
483
- font-size: 0.875rem;
484
- }
485
- .pf-table-row { }
486
- /* Table({ striped: true }) — shade alternate body rows. */
487
605
  .pf-table-striped tbody .pf-table-row:nth-child(even) {
488
606
  background: color-mix(in oklab, var(--muted) 40%, transparent);
489
607
  }
490
- .pf-table-header {
491
- text-align: left;
492
- padding: 0.75rem 1rem;
493
- font-weight: 600;
494
- border-bottom: 2px solid var(--border);
495
- }
496
- .pf-table-cell {
497
- padding: 0.75rem 1rem;
498
- border-bottom: 1px solid var(--border);
499
- }
608
+ .pf-tfoot .pf-table-cell { font-weight: 500; background: color-mix(in oklab, var(--muted) 45%, transparent); }
500
609
  .pf-table-caption {
501
610
  caption-side: bottom;
502
- padding: 0.5rem;
611
+ padding-top: 0.75rem;
503
612
  color: var(--muted-foreground);
504
- font-size: 0.875rem;
613
+ font-size: 0.8125rem;
505
614
  }
506
615
 
507
- .pf-expandable-row { }
616
+ .pf-expandable-row { border-bottom: 1px solid var(--border); }
508
617
  .pf-expandable-row-summary {
509
618
  display: flex;
510
619
  align-items: center;
511
620
  gap: 0.5rem;
621
+ width: 100%;
622
+ padding: 0.625rem 0;
623
+ font-size: 0.875rem;
624
+ font-weight: 500;
625
+ text-align: left;
512
626
  cursor: pointer;
513
627
  user-select: none;
514
628
  }
515
629
  .pf-expandable-arrow {
516
630
  display: inline-block;
631
+ flex-shrink: 0;
632
+ width: 0.4375rem;
633
+ height: 0.4375rem;
634
+ margin: 0 0.25rem;
635
+ border-right: 1.5px solid var(--muted-foreground);
636
+ border-bottom: 1.5px solid var(--muted-foreground);
637
+ transform: rotate(-45deg);
517
638
  transition: transform 0.2s;
518
639
  }
519
- .pf-expandable-row-detail {
520
- padding-left: 1.5rem;
521
- }
640
+ .pf-expandable-row-summary[aria-expanded="true"] .pf-expandable-arrow { transform: rotate(45deg); }
641
+ .pf-expandable-row-detail { padding: 0 0 0.75rem 1.5rem; }
522
642
 
523
- /* ═══════════════════════════════════════════════════════════════════════════
524
- 11. FORM
525
- ═══════════════════════════════════════════════════════════════════════════ */
643
+ .pf-ring[data-variant="success"] .pf-ring-fill, .pf-progress[data-variant="success"] .pf-progress-fill { stroke: var(--success); background: var(--success); }
644
+ .pf-ring[data-variant="warning"] .pf-ring-fill, .pf-progress[data-variant="warning"] .pf-progress-fill { stroke: var(--warning); background: var(--warning); }
645
+ .pf-ring[data-variant="destructive"] .pf-ring-fill, .pf-progress[data-variant="destructive"] .pf-progress-fill { stroke: var(--destructive); background: var(--destructive); }
646
+ .pf-ring[data-variant="info"] .pf-ring-fill, .pf-progress[data-variant="info"] .pf-progress-fill { stroke: var(--info); background: var(--info); }
526
647
 
527
648
  .pf-form { display: flex; flex-direction: column; gap: 1rem; }
528
649
 
529
- .pf-input-wrapper, .pf-textarea-wrapper, .pf-select-wrapper, .pf-slider-wrapper {
650
+ .pf-labeled, .pf-input-wrapper, .pf-textarea-wrapper, .pf-select-wrapper, .pf-slider-wrapper, .pf-field {
530
651
  display: flex;
531
652
  flex-direction: column;
532
- gap: 0.375rem;
653
+ gap: 0.5rem;
654
+ min-width: 0;
533
655
  }
534
656
 
535
- .pf-input-label {
657
+ .pf-input-label, .pf-field-title {
536
658
  font-size: 0.875rem;
537
659
  font-weight: 500;
660
+ line-height: 1.25rem;
538
661
  }
662
+ .pf-input-label[data-required]::after, .pf-radio-legend[data-required]::after { content: " *"; color: var(--destructive); }
539
663
 
540
- .pf-input, .pf-textarea, .pf-select {
541
- padding: 0.5rem 0.75rem;
664
+ .pf-input, .pf-textarea, .pf-select, .pf-combobox-input, .pf-datatable-search {
665
+ display: block;
666
+ width: 100%;
667
+ min-height: 2.25rem;
668
+ padding: 0.4375rem 0.75rem;
542
669
  border: 1px solid var(--input);
543
670
  border-radius: var(--radius-sm);
544
- font-size: 0.875rem;
545
671
  background: var(--background);
546
672
  color: var(--foreground);
673
+ font-size: 0.875rem;
674
+ line-height: 1.25rem;
675
+ box-shadow: var(--shadow-sm);
547
676
  transition: border-color 0.15s, box-shadow 0.15s;
548
677
  }
549
- .pf-input:focus, .pf-textarea:focus, .pf-select:focus {
550
- outline: 2px solid var(--ring);
551
- outline-offset: -1px;
678
+ :is(.pf-input, .pf-textarea, .pf-combobox-input, .pf-datatable-search)::placeholder {
679
+ color: var(--muted-foreground);
680
+ opacity: 1;
681
+ }
682
+ :is(.pf-input, .pf-textarea, .pf-select, .pf-combobox-input, .pf-datatable-search):focus-visible {
683
+ outline: none;
552
684
  border-color: var(--ring);
685
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 25%, transparent);
686
+ }
687
+ :is(.pf-input, .pf-textarea, .pf-select, .pf-combobox-input)[aria-invalid="true"] { border-color: var(--destructive); }
688
+ :is(.pf-input, .pf-textarea, .pf-select, .pf-combobox-input)[aria-invalid="true"]:focus-visible {
689
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 25%, transparent);
553
690
  }
691
+ :is(.pf-input, .pf-textarea, .pf-select, .pf-combobox-input):disabled { opacity: 0.5; cursor: not-allowed; }
554
692
  .pf-textarea { min-height: 5rem; resize: vertical; }
693
+ .pf-datatable-search { max-width: 20rem; }
694
+ .pf-input[type="date"] { cursor: text; }
695
+ .pf-input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: 0.6; }
696
+ .pf-input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
697
+
698
+ .pf-select:not([multiple]) {
699
+ appearance: none;
700
+ padding-right: 2.25rem;
701
+ background-image:
702
+ linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
703
+ linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
704
+ background-position: calc(100% - 1.125rem) 52%, calc(100% - 0.8125rem) 52%;
705
+ background-size: 0.3125rem 0.3125rem;
706
+ background-repeat: no-repeat;
707
+ cursor: pointer;
708
+ }
709
+ .pf-select[multiple] { padding: 0.25rem; }
710
+ .pf-select[multiple] option { padding: 0.375rem 0.5rem; border-radius: calc(var(--radius-sm) - 2px); }
711
+ .pf-select-group { display: contents; }
712
+ .pf-select-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.25rem 0; }
555
713
 
556
- /* Buttons */
557
714
  .pf-button {
558
715
  display: inline-flex;
559
716
  align-items: center;
560
717
  justify-content: center;
561
718
  gap: 0.5rem;
562
- padding: 0.5rem 1rem;
563
- border: none;
719
+ flex-shrink: 0;
720
+ height: 2.25rem;
721
+ padding: 0 1rem;
722
+ border: 1px solid transparent;
564
723
  border-radius: var(--radius-sm);
565
724
  font-size: 0.875rem;
566
725
  font-weight: 500;
567
- cursor: pointer;
568
- transition: opacity 0.15s, background-color 0.15s;
726
+ line-height: 1;
569
727
  white-space: nowrap;
728
+ text-decoration: none;
729
+ cursor: pointer;
730
+ user-select: none;
731
+ transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
570
732
  }
571
- .pf-button:hover { opacity: 0.9; }
572
- .pf-button:active { opacity: 0.8; }
573
733
  .pf-button:disabled { opacity: 0.5; cursor: not-allowed; }
734
+ .pf-button:active:not(:disabled) { transform: translateY(0.5px); }
574
735
 
575
- .pf-button[data-variant="default"] { background: var(--primary); color: var(--primary-foreground); }
736
+ .pf-button[data-variant="default"] { background: var(--primary); color: var(--primary-foreground); box-shadow: var(--shadow-sm); }
576
737
  .pf-button[data-variant="secondary"] { background: var(--secondary); color: var(--secondary-foreground); }
577
- .pf-button[data-variant="destructive"] { background: var(--destructive); color: var(--destructive-foreground); }
738
+ .pf-button[data-variant="destructive"] { background: var(--destructive); color: var(--destructive-foreground); box-shadow: var(--shadow-sm); }
739
+ .pf-button[data-variant="outline"] { background: var(--background); color: var(--foreground); border-color: var(--input); box-shadow: var(--shadow-sm); }
578
740
  .pf-button[data-variant="ghost"] { background: transparent; color: var(--foreground); }
579
- .pf-button[data-variant="ghost"]:hover { background: var(--accent); }
580
- .pf-button[data-variant="outline"] { background: transparent; color: var(--foreground); border: 1px solid var(--border); }
581
- .pf-button[data-variant="outline"]:hover { background: var(--accent); }
582
- .pf-button[data-variant="link"] { background: transparent; color: var(--primary); text-decoration: underline; padding: 0; }
741
+ .pf-button[data-variant="link"] { height: auto; padding: 0; background: transparent; color: var(--primary); text-underline-offset: 4px; }
583
742
 
584
- .pf-button-group { display: flex; gap: 0.5rem; flex-wrap: wrap; }
743
+ .pf-button[data-variant="default"]:hover:not(:disabled) { background: color-mix(in oklab, var(--primary) 88%, var(--foreground)); }
744
+ .pf-button[data-variant="secondary"]:hover:not(:disabled) { background: color-mix(in oklab, var(--secondary) 80%, var(--foreground)); }
745
+ .pf-button[data-variant="destructive"]:hover:not(:disabled) { background: color-mix(in oklab, var(--destructive) 88%, var(--foreground)); }
746
+ .pf-button[data-variant="outline"]:hover:not(:disabled),
747
+ .pf-button[data-variant="ghost"]:hover:not(:disabled) { background: var(--muted); }
748
+ .pf-button[data-variant="link"]:hover:not(:disabled) { text-decoration: underline; }
585
749
 
586
- /* Checkbox, Switch, Slider, Radio */
587
- .pf-checkbox-wrapper, .pf-switch-wrapper {
588
- display: flex;
589
- align-items: center;
590
- gap: 0.5rem;
591
- cursor: pointer;
592
- }
593
- .pf-checkbox, .pf-switch { accent-color: var(--primary); }
750
+ .pf-button[data-size="sm"] { height: 2rem; padding: 0 0.75rem; font-size: 0.8125rem; gap: 0.375rem; }
751
+ .pf-button[data-size="lg"] { height: 2.75rem; padding: 0 1.5rem; font-size: 0.9375rem; border-radius: var(--radius); }
752
+ .pf-button[data-size="icon"] { width: 2.25rem; padding: 0; }
594
753
 
595
- .pf-slider { width: 100%; accent-color: var(--primary); }
754
+ .pf-button-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
596
755
 
597
- .pf-radio {
598
- display: flex;
756
+ .pf-checkbox-wrapper, .pf-switch-wrapper, .pf-radio {
757
+ display: inline-flex;
599
758
  align-items: center;
600
- gap: 0.5rem;
759
+ align-self: flex-start;
760
+ gap: 0.625rem;
761
+ font-size: 0.875rem;
762
+ line-height: 1.25rem;
601
763
  cursor: pointer;
764
+ user-select: none;
602
765
  }
603
- .pf-radio-label { font-size: 0.875rem; }
604
- .pf-radio-group {
605
- border: none;
606
- padding: 0;
766
+ .pf-checkbox, .pf-radio-input {
767
+ flex-shrink: 0;
768
+ width: 1rem;
769
+ height: 1rem;
607
770
  margin: 0;
608
- display: flex;
609
- flex-direction: column;
610
- gap: 0.5rem;
771
+ accent-color: var(--primary);
772
+ cursor: pointer;
611
773
  }
612
774
 
613
- /* Select separator */
614
- .pf-select-group { }
615
- .pf-select-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.25rem 0; }
775
+ .pf-switch {
776
+ appearance: none;
777
+ position: relative;
778
+ flex-shrink: 0;
779
+ width: 2.25rem;
780
+ height: 1.25rem;
781
+ margin: 0;
782
+ border: 0;
783
+ border-radius: 9999px;
784
+ background: color-mix(in oklab, var(--input) 65%, var(--muted-foreground));
785
+ cursor: pointer;
786
+ transition: background-color 0.2s;
787
+ }
788
+ .pf-switch::before {
789
+ content: "";
790
+ position: absolute;
791
+ top: 0.125rem;
792
+ left: 0.125rem;
793
+ width: 1rem;
794
+ height: 1rem;
795
+ border-radius: 50%;
796
+ background: #fff;
797
+ box-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
798
+ transition: transform 0.2s;
799
+ }
800
+ .pf-switch:checked { background: var(--primary); }
801
+ .pf-switch:checked::before { transform: translateX(1rem); }
802
+ .pf-switch:disabled, .pf-checkbox:disabled { opacity: 0.5; cursor: not-allowed; }
616
803
 
617
- /* Field */
618
- .pf-field {
804
+ .pf-radio-group {
619
805
  display: flex;
620
806
  flex-direction: column;
621
- gap: 0.375rem;
807
+ gap: 0.625rem;
808
+ min-width: 0;
809
+ margin: 0;
810
+ padding: 0;
811
+ border: 0;
622
812
  }
623
- .pf-field-title { font-size: 0.875rem; font-weight: 500; }
624
- .pf-field-description { font-size: 0.75rem; color: var(--muted-foreground); }
625
- .pf-field-content { }
626
- .pf-field-error { font-size: 0.75rem; color: var(--destructive); }
627
-
628
- /* Combobox */
629
- .pf-combobox { position: relative; }
630
- .pf-combobox-input {
813
+ .pf-radio-legend {
814
+ float: left;
631
815
  width: 100%;
632
- padding: 0.5rem 0.75rem;
633
- border: 1px solid var(--input);
634
- border-radius: var(--radius-sm);
816
+ margin-bottom: 0.125rem;
817
+ padding: 0;
635
818
  font-size: 0.875rem;
819
+ font-weight: 500;
820
+ line-height: 1.25rem;
821
+ }
822
+ .pf-radio-legend + * { clear: both; }
823
+
824
+ .pf-slider {
825
+ appearance: none;
826
+ width: 100%;
827
+ height: 1.25rem;
828
+ margin: 0;
829
+ background: transparent;
830
+ cursor: pointer;
831
+ }
832
+ .pf-slider::-webkit-slider-runnable-track {
833
+ height: 0.375rem;
834
+ border-radius: 9999px;
835
+ background:
836
+ linear-gradient(var(--primary), var(--primary)) 0 / var(--pf-fill, 50%) 100% no-repeat,
837
+ var(--muted);
838
+ }
839
+ .pf-slider::-moz-range-track { height: 0.375rem; border-radius: 9999px; background: var(--muted); }
840
+ .pf-slider::-moz-range-progress { height: 0.375rem; border-radius: 9999px; background: var(--primary); }
841
+ .pf-slider::-webkit-slider-thumb {
842
+ appearance: none;
843
+ width: 1rem;
844
+ height: 1rem;
845
+ margin-top: -0.3125rem;
846
+ border: 2px solid var(--primary);
847
+ border-radius: 50%;
636
848
  background: var(--background);
637
- color: var(--foreground);
849
+ box-shadow: var(--shadow-sm);
850
+ transition: box-shadow 0.15s;
638
851
  }
639
- .pf-combobox-input:focus {
640
- outline: 2px solid var(--ring);
641
- outline-offset: -1px;
852
+ .pf-slider::-moz-range-thumb {
853
+ width: 0.75rem;
854
+ height: 0.75rem;
855
+ border: 2px solid var(--primary);
856
+ border-radius: 50%;
857
+ background: var(--background);
642
858
  }
859
+ .pf-slider:focus-visible { outline: none; }
860
+ .pf-slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px color-mix(in oklab, var(--ring) 30%, transparent); }
861
+ .pf-slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px color-mix(in oklab, var(--ring) 30%, transparent); }
862
+
863
+ .pf-field-description { font-size: 0.8125rem; line-height: 1.25rem; color: var(--muted-foreground); }
864
+ .pf-field-content { display: flex; flex-direction: column; gap: 0.5rem; }
865
+ .pf-field-error { margin: 0; font-size: 0.8125rem; line-height: 1.25rem; font-weight: 500; color: var(--destructive); }
866
+
867
+ .pf-combobox { position: relative; }
643
868
  .pf-combobox-dropdown {
644
869
  position: absolute;
645
- top: 100%;
870
+ top: calc(100% + 0.25rem);
646
871
  left: 0;
647
872
  right: 0;
648
873
  z-index: 50;
649
- margin-top: 0.25rem;
874
+ max-height: 15rem;
875
+ overflow-y: auto;
876
+ padding: 0.25rem;
650
877
  background: var(--popover);
651
878
  color: var(--popover-foreground);
652
879
  border: 1px solid var(--border);
653
880
  border-radius: var(--radius-sm);
654
- box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
655
- max-height: 15rem;
656
- overflow-y: auto;
881
+ box-shadow: var(--shadow-md);
882
+ animation: pf-pop-in 0.12s ease-out;
657
883
  }
658
884
  .pf-combobox-option {
659
- padding: 0.5rem 0.75rem;
660
- cursor: pointer;
885
+ padding: 0.375rem 0.5rem;
886
+ border-radius: calc(var(--radius-sm) - 2px);
661
887
  font-size: 0.875rem;
888
+ cursor: pointer;
662
889
  }
663
- .pf-combobox-option:hover { background: var(--accent); }
664
- .pf-combobox-group { }
665
- .pf-combobox-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.5rem 0.75rem 0.25rem; }
890
+ .pf-combobox-option:hover, .pf-combobox-option[aria-selected="true"] { background: var(--muted); }
891
+ .pf-combobox-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.375rem 0.5rem 0.25rem; }
892
+ .pf-combobox-dropdown .pf-separator, .pf-select-wrapper .pf-separator { margin: 0.25rem -0.25rem; width: auto; }
666
893
 
667
- /* Calendar & DatePicker */
668
- .pf-calendar {
669
- border: 1px solid var(--border);
670
- border-radius: var(--radius-sm);
671
- padding: 0.75rem;
672
- font-size: 0.875rem;
673
- }
674
- .pf-datepicker {
894
+ .pf-calendar, .pf-datepicker { display: flex; flex-direction: column; gap: 0.5rem; }
895
+
896
+ .pf-choice-card {
675
897
  display: flex;
676
898
  flex-direction: column;
677
- gap: 0.375rem;
899
+ gap: 0.25rem;
900
+ padding: 1rem;
901
+ border: 1px solid var(--border);
902
+ border-radius: var(--radius);
903
+ background: var(--card);
904
+ cursor: pointer;
905
+ transition: border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
678
906
  }
907
+ .pf-choice-card:hover { border-color: color-mix(in oklab, var(--primary) 40%, var(--border)); }
908
+ .pf-choice-card[data-selected="true"] {
909
+ border-color: var(--primary);
910
+ background: color-mix(in oklab, var(--primary) 6%, var(--card));
911
+ box-shadow: 0 0 0 1px var(--primary);
912
+ }
913
+ .pf-choice-card-label { font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; }
914
+ .pf-choice-card-description { font-size: 0.8125rem; line-height: 1.25rem; color: var(--muted-foreground); }
679
915
 
680
- /* ChoiceCard */
681
- .pf-choice-card {
682
- border: 2px solid var(--border);
916
+ .pf-dropzone {
917
+ display: flex;
918
+ flex-direction: column;
919
+ align-items: center;
920
+ justify-content: center;
921
+ gap: 0.5rem;
922
+ padding: 2rem 1.5rem;
923
+ border: 1.5px dashed var(--input);
683
924
  border-radius: var(--radius);
684
- padding: 1rem;
925
+ text-align: center;
926
+ font-size: 0.875rem;
927
+ color: var(--muted-foreground);
685
928
  cursor: pointer;
686
- transition: border-color 0.15s, background-color 0.15s;
929
+ transition: border-color 0.15s, background-color 0.15s, color 0.15s;
930
+ }
931
+ .pf-dropzone:hover, .pf-dropzone.pf-dropzone--active {
932
+ border-color: var(--primary);
933
+ background: color-mix(in oklab, var(--primary) 5%, transparent);
934
+ color: var(--foreground);
687
935
  }
688
- .pf-choice-card:hover { border-color: var(--ring); }
689
- .pf-choice-card-label { font-weight: 500; }
690
- .pf-choice-card-description { font-size: 0.875rem; color: var(--muted-foreground); margin-top: 0.25rem; }
691
-
692
- /* ═══════════════════════════════════════════════════════════════════════════
693
- 12. TABS
694
- ═══════════════════════════════════════════════════════════════════════════ */
695
936
 
696
- .pf-tabs { }
937
+ .pf-tabs { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
697
938
  .pf-tabs-bar {
698
939
  display: flex;
699
- gap: 0;
940
+ gap: 0.25rem;
941
+ overflow-x: auto;
700
942
  border-bottom: 1px solid var(--border);
701
- margin-bottom: 1rem;
943
+ scrollbar-width: none;
702
944
  }
703
945
  .pf-tab-trigger {
704
- padding: 0.5rem 1rem;
946
+ flex-shrink: 0;
947
+ margin-bottom: -1px;
948
+ padding: 0.5rem 0.875rem;
949
+ border: 0;
950
+ border-bottom: 2px solid transparent;
951
+ background: transparent;
952
+ color: var(--muted-foreground);
705
953
  font-size: 0.875rem;
706
954
  font-weight: 500;
955
+ line-height: 1.25rem;
956
+ white-space: nowrap;
707
957
  cursor: pointer;
708
- background: transparent;
709
- border: none;
710
- border-bottom: 2px solid transparent;
711
- color: var(--muted-foreground);
712
958
  transition: color 0.15s, border-color 0.15s;
713
959
  }
714
960
  .pf-tab-trigger:hover { color: var(--foreground); }
@@ -716,12 +962,8 @@
716
962
  color: var(--foreground);
717
963
  border-bottom-color: var(--primary);
718
964
  }
719
- .pf-tab-panel { }
720
- .pf-tab { }
721
-
722
- /* ═══════════════════════════════════════════════════════════════════════════
723
- 13. ACCORDION
724
- ═══════════════════════════════════════════════════════════════════════════ */
965
+ .pf-tab-trigger:focus-visible { outline-offset: -2px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
966
+ .pf-tab-panel:focus-visible { outline-offset: 4px; border-radius: var(--radius-sm); }
725
967
 
726
968
  .pf-accordion { display: flex; flex-direction: column; }
727
969
  .pf-accordion-item { border-bottom: 1px solid var(--border); }
@@ -729,215 +971,205 @@
729
971
  display: flex;
730
972
  align-items: center;
731
973
  justify-content: space-between;
974
+ gap: 1rem;
732
975
  width: 100%;
733
976
  padding: 1rem 0;
977
+ border: 0;
978
+ background: transparent;
734
979
  font-size: 0.875rem;
735
980
  font-weight: 500;
736
- cursor: pointer;
737
- background: transparent;
738
- border: none;
981
+ line-height: 1.25rem;
739
982
  text-align: left;
740
- color: var(--foreground);
983
+ cursor: pointer;
741
984
  }
742
- .pf-accordion-trigger:hover { text-decoration: underline; }
743
- .pf-accordion-content { padding-bottom: 1rem; }
985
+ .pf-accordion-trigger:hover { text-decoration: underline; text-underline-offset: 4px; }
986
+ .pf-accordion-trigger::after {
987
+ content: "";
988
+ flex-shrink: 0;
989
+ width: 0.4375rem;
990
+ height: 0.4375rem;
991
+ margin-right: 0.25rem;
992
+ border-right: 1.5px solid var(--muted-foreground);
993
+ border-bottom: 1.5px solid var(--muted-foreground);
994
+ transform: translateY(-25%) rotate(45deg);
995
+ transition: transform 0.2s;
996
+ }
997
+ .pf-accordion-trigger[aria-expanded="true"]::after { transform: translateY(25%) rotate(-135deg); }
998
+ .pf-accordion-trigger:focus-visible { outline-offset: -2px; border-radius: var(--radius-sm); }
999
+ .pf-accordion-content { padding-bottom: 1rem; font-size: 0.875rem; line-height: 1.5rem; }
744
1000
 
745
- /* ═══════════════════════════════════════════════════════════════════════════
746
- 14. DIALOG
747
- ═══════════════════════════════════════════════════════════════════════════ */
1001
+ .pf-carousel { position: relative; overflow: hidden; border-radius: var(--radius); }
1002
+ .pf-carousel-track {
1003
+ display: flex;
1004
+ transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
1005
+ }
1006
+ .pf-carousel-track > * { flex: 0 0 100%; min-width: 0; }
1007
+ .pf-carousel-prev,
1008
+ .pf-carousel-next {
1009
+ position: absolute;
1010
+ top: 50%;
1011
+ z-index: 10;
1012
+ display: flex;
1013
+ align-items: center;
1014
+ justify-content: center;
1015
+ width: 2rem;
1016
+ height: 2rem;
1017
+ padding: 0 0 0.125rem;
1018
+ border: 1px solid var(--border);
1019
+ border-radius: 50%;
1020
+ background: color-mix(in oklab, var(--background) 85%, transparent);
1021
+ color: var(--foreground);
1022
+ font-size: 1.25rem;
1023
+ line-height: 1;
1024
+ box-shadow: var(--shadow-sm);
1025
+ backdrop-filter: blur(4px);
1026
+ cursor: pointer;
1027
+ transform: translateY(-50%);
1028
+ transition: opacity 0.15s, background-color 0.15s;
1029
+ }
1030
+ .pf-carousel-prev { left: 0.5rem; }
1031
+ .pf-carousel-next { right: 0.5rem; }
1032
+ .pf-carousel-prev:hover:not(:disabled),
1033
+ .pf-carousel-next:hover:not(:disabled) { background: var(--muted); }
1034
+ .pf-carousel-prev:disabled,
1035
+ .pf-carousel-next:disabled { opacity: 0; pointer-events: none; }
748
1036
 
749
- .pf-dialog-wrapper { }
750
1037
  .pf-dialog {
1038
+ position: fixed;
1039
+ width: calc(100% - 2rem);
1040
+ max-width: 32rem;
1041
+ max-height: calc(100% - 2rem);
1042
+ overflow-y: auto;
1043
+ padding: 1.5rem;
751
1044
  background: var(--card);
752
1045
  color: var(--card-foreground);
753
1046
  border: 1px solid var(--border);
754
- border-radius: var(--radius);
755
- padding: 1.5rem;
756
- max-width: 32rem;
757
- width: 90vw;
1047
+ border-radius: var(--radius-lg);
1048
+ box-shadow: var(--shadow-lg);
1049
+ font-family: var(--font-sans);
1050
+ line-height: 1.5;
758
1051
  }
1052
+ .pf-dialog[open] { animation: pf-dialog-in 0.16s ease-out; }
759
1053
  .pf-dialog::backdrop {
760
- background: rgba(0, 0, 0, 0.5);
1054
+ background: rgb(0 0 0 / 0.55);
1055
+ backdrop-filter: blur(2px);
1056
+ animation: pf-fade-in 0.16s ease-out;
1057
+ }
1058
+ .pf-dialog-title { margin: 0 0 0.375rem; padding-right: 2rem; font-size: 1.125rem; font-weight: 600; line-height: 1.75rem; letter-spacing: -0.01em; }
1059
+ .pf-dialog-desc { margin: 0 0 1.25rem; color: var(--muted-foreground); font-size: 0.875rem; line-height: 1.25rem; }
1060
+ .pf-dialog-body { display: flex; flex-direction: column; gap: 1rem; }
1061
+ .pf-dialog-close {
1062
+ position: absolute;
1063
+ top: 1rem;
1064
+ right: 1rem;
1065
+ display: flex;
1066
+ align-items: center;
1067
+ justify-content: center;
1068
+ width: 1.75rem;
1069
+ height: 1.75rem;
1070
+ padding: 0;
1071
+ border: 0;
1072
+ border-radius: var(--radius-sm);
1073
+ background: transparent;
1074
+ color: var(--muted-foreground);
1075
+ font-size: 1.25rem;
1076
+ line-height: 1;
1077
+ cursor: pointer;
1078
+ transition: color 0.15s, background-color 0.15s;
761
1079
  }
762
- .pf-dialog-title { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 600; }
763
- .pf-dialog-desc { margin: 0 0 1rem; color: var(--muted-foreground); font-size: 0.875rem; }
764
- .pf-dialog-body { }
1080
+ .pf-dialog-close:hover { color: var(--foreground); background: var(--muted); }
765
1081
 
766
- /* ═══════════════════════════════════════════════════════════════════════════
767
- 15. POPOVER, TOOLTIP, HOVER CARD
768
- ═══════════════════════════════════════════════════════════════════════════ */
1082
+ .pf-popover, .pf-tooltip, .pf-hover-card { position: relative; display: inline-block; }
769
1083
 
770
- .pf-popover { position: relative; display: inline-block; }
771
- .pf-popover-content {
1084
+ .pf-popover-content, .pf-hover-card-content {
772
1085
  position: absolute;
1086
+ top: calc(100% + 0.5rem);
1087
+ left: 0;
773
1088
  z-index: 50;
774
1089
  min-width: 12rem;
775
- padding: 1rem;
1090
+ max-width: min(20rem, calc(100vw - 2rem));
1091
+ padding: 0.875rem 1rem;
776
1092
  background: var(--popover);
777
1093
  color: var(--popover-foreground);
778
1094
  border: 1px solid var(--border);
779
1095
  border-radius: var(--radius);
780
- box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
1096
+ box-shadow: var(--shadow-md);
1097
+ font-size: 0.875rem;
1098
+ line-height: 1.25rem;
1099
+ animation: pf-pop-in 0.12s ease-out;
781
1100
  }
782
- .pf-popover-title { font-weight: 600; margin-bottom: 0.5rem; }
1101
+ .pf-hover-card-content { min-width: 16rem; }
1102
+ .pf-hover-card-content::before {
1103
+ content: "";
1104
+ position: absolute;
1105
+ left: 0;
1106
+ right: 0;
1107
+ bottom: 100%;
1108
+ height: 0.5rem;
1109
+ }
1110
+ .pf-popover-title { margin-bottom: 0.375rem; font-weight: 600; }
783
1111
 
784
- .pf-tooltip { position: relative; display: inline-block; }
785
1112
  .pf-tooltip-content {
786
1113
  position: absolute;
787
- z-index: 50;
788
- bottom: 100%;
1114
+ bottom: calc(100% + 0.375rem);
789
1115
  left: 50%;
790
- transform: translateX(-50%);
791
- margin-bottom: 0.5rem;
792
- padding: 0.375rem 0.75rem;
1116
+ z-index: 50;
1117
+ padding: 0.375rem 0.625rem;
793
1118
  background: var(--foreground);
794
1119
  color: var(--background);
795
1120
  border-radius: var(--radius-sm);
796
1121
  font-size: 0.75rem;
1122
+ font-weight: 500;
1123
+ line-height: 1rem;
797
1124
  white-space: nowrap;
798
1125
  pointer-events: none;
1126
+ transform: translateX(-50%);
1127
+ animation: pf-tooltip-in 0.12s ease-out;
799
1128
  }
800
1129
 
801
- .pf-hover-card { position: relative; display: inline-block; }
802
- .pf-hover-card-content {
803
- position: absolute;
804
- z-index: 50;
805
- min-width: 16rem;
806
- padding: 1rem;
807
- background: var(--card);
808
- color: var(--card-foreground);
809
- border: 1px solid var(--border);
810
- border-radius: var(--radius);
811
- box-shadow: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);
812
- }
813
-
814
- /* ═══════════════════════════════════════════════════════════════════════════
815
- 16. CAROUSEL
816
- ═══════════════════════════════════════════════════════════════════════════ */
817
-
818
- .pf-carousel { position: relative; overflow: hidden; }
819
- .pf-carousel-track {
820
- display: flex;
821
- transition: transform 0.3s ease;
822
- }
823
- .pf-carousel-track > * { flex: 0 0 100%; min-width: 0; }
824
-
825
- .pf-carousel-prev,
826
- .pf-carousel-next {
827
- position: absolute;
828
- top: 50%;
829
- transform: translateY(-50%);
830
- z-index: 10;
831
- width: 2rem;
832
- height: 2rem;
833
- display: flex;
834
- align-items: center;
835
- justify-content: center;
836
- border-radius: 50%;
837
- border: 1px solid var(--border);
838
- background: var(--card);
839
- color: var(--foreground);
840
- cursor: pointer;
841
- font-size: 1rem;
842
- }
843
- .pf-carousel-prev { left: 0.5rem; }
844
- .pf-carousel-next { right: 0.5rem; }
845
- .pf-carousel-prev:hover,
846
- .pf-carousel-next:hover { background: var(--accent); }
847
-
848
- /* ═══════════════════════════════════════════════════════════════════════════
849
- 17. CHARTS
850
- ═══════════════════════════════════════════════════════════════════════════ */
1130
+ @keyframes pf-fade-in { from { opacity: 0; } }
1131
+ @keyframes pf-pop-in { from { opacity: 0; transform: translateY(-0.25rem); } }
1132
+ @keyframes pf-tooltip-in { from { opacity: 0; transform: translate(-50%, 0.25rem); } }
1133
+ @keyframes pf-dialog-in { from { opacity: 0; transform: translateY(0.5rem) scale(0.98); } }
851
1134
 
852
- .pf-chart { position: relative; }
853
- .pf-chart svg { display: block; width: 100%; height: auto; }
1135
+ .pf-chart { position: relative; min-width: 0; }
1136
+ .pf-chart svg { display: block; max-width: 100%; height: auto; margin: 0 auto; overflow: visible; }
1137
+ .pf-chart text { font-family: var(--font-sans); font-variant-numeric: tabular-nums; }
854
1138
 
855
1139
  .pf-chart-tooltip {
856
1140
  position: absolute;
857
1141
  pointer-events: none;
858
1142
  z-index: 50;
859
- background: var(--popover, #fff);
860
- color: var(--popover-foreground, #09090b);
861
- border: 1px solid var(--border, #e5e7eb);
862
- border-radius: var(--radius, 0.375rem);
1143
+ background: var(--popover);
1144
+ color: var(--popover-foreground);
1145
+ border: 1px solid var(--border);
1146
+ border-radius: var(--radius-sm);
863
1147
  padding: 0.375rem 0.625rem;
864
1148
  font-size: 0.75rem;
865
1149
  line-height: 1.25rem;
866
- box-shadow: 0 2px 8px rgb(0 0 0 / 0.12);
1150
+ box-shadow: var(--shadow-md);
867
1151
  white-space: nowrap;
868
1152
  opacity: 0;
869
1153
  transition: opacity 0.15s ease;
870
1154
  }
871
1155
  .pf-chart-tooltip.pf-visible { opacity: 1; }
872
- .pf-chart-tooltip-label { font-weight: 500; margin-bottom: 0.125rem; }
873
- .pf-chart-tooltip-row { display: flex; align-items: center; gap: 0.375rem; }
874
- .pf-chart-tooltip-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
1156
+ .pf-chart-tooltip-label { font-weight: 600; margin-bottom: 0.125rem; }
1157
+ .pf-chart-tooltip-row { display: flex; align-items: center; gap: 0.375rem; font-variant-numeric: tabular-nums; }
1158
+ .pf-chart-tooltip-dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
875
1159
 
876
- .pf-chart-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.75rem; font-size: 0.75rem; }
1160
+ .pf-chart-legend { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-bottom: 0.75rem; font-size: 0.75rem; color: var(--muted-foreground); }
877
1161
  .pf-chart-legend-item { display: flex; align-items: center; gap: 0.375rem; }
1162
+ .pf-chart-legend-dot { width: 0.5rem; height: 0.5rem; border-radius: 2px; flex-shrink: 0; }
878
1163
 
879
- /* ═══════════════════════════════════════════════════════════════════════════
880
- 18. MEDIA
881
- ═══════════════════════════════════════════════════════════════════════════ */
882
-
883
- .pf-image { max-width: 100%; height: auto; display: block; }
1164
+ .pf-image { max-width: 100%; height: auto; display: block; border-radius: var(--radius-sm); }
884
1165
  .pf-audio { width: 100%; }
885
- .pf-video { max-width: 100%; height: auto; display: block; }
886
- .pf-embed { position: relative; overflow: hidden; }
887
- .pf-embed iframe { border: none; }
1166
+ .pf-video { max-width: 100%; height: auto; display: block; border-radius: var(--radius-sm); }
1167
+ .pf-embed { position: relative; overflow: hidden; border-radius: var(--radius-sm); }
1168
+ .pf-embed iframe { display: block; width: 100%; border: none; }
888
1169
  .pf-svg { display: inline-block; }
889
1170
  .pf-mermaid { overflow-x: auto; }
890
1171
 
891
- .pf-dropzone {
892
- border: 2px dashed var(--border);
893
- border-radius: var(--radius);
894
- padding: 2rem;
895
- text-align: center;
896
- color: var(--muted-foreground);
897
- cursor: pointer;
898
- transition: border-color 0.15s;
899
- }
900
- .pf-dropzone:hover, .pf-dropzone.pf-dropzone--active {
901
- border-color: var(--primary);
902
- }
903
-
904
- /* ═══════════════════════════════════════════════════════════════════════════
905
- 19. TOAST
906
- ═══════════════════════════════════════════════════════════════════════════ */
907
-
908
- .pf-toast {
909
- background: var(--card);
910
- color: var(--card-foreground);
911
- border: 1px solid var(--border);
912
- border-radius: var(--radius);
913
- padding: 1rem;
914
- box-shadow: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);
915
- max-width: 24rem;
916
- }
917
- .pf-toast--success {
918
- border-color: var(--success, #22c55e);
919
- background: color-mix(in srgb, var(--success, #22c55e) 10%, var(--card));
920
- }
921
- .pf-toast--error {
922
- border-color: var(--destructive);
923
- background: color-mix(in srgb, var(--destructive) 10%, var(--card));
924
- }
925
- .pf-toast--warning {
926
- border-color: var(--warning, #f59e0b);
927
- background: color-mix(in srgb, var(--warning, #f59e0b) 10%, var(--card));
928
- }
929
- .pf-toast--info {
930
- border-color: var(--primary);
931
- background: color-mix(in srgb, var(--primary) 10%, var(--card));
932
- }
933
-
934
- /* ═══════════════════════════════════════════════════════════════════════════
935
- 20. UTILITY — Tailwind-compatible helpers for cssClass
936
- ═══════════════════════════════════════════════════════════════════════════
937
- All classes used by auto-renderers and builders are defined here so the
938
- bundle works without Tailwind. The scale mirrors Tailwind's default
939
- spacing (1 unit = 0.25rem) and typography tokens.
940
- ═══════════════════════════════════════════════════════════════════════════ */
1172
+ /* Tailwind-compatible helpers for cssClass, so the bundle works without Tailwind. */
941
1173
 
942
1174
  /* ── Display ──────────────────────────────────────────────────────────────── */
943
1175