@maxhealth.tech/prefab 0.1.6 → 0.1.9

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 (61) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +70 -3
  3. package/dist/app.d.ts +5 -1
  4. package/dist/app.d.ts.map +1 -1
  5. package/dist/app.js +18 -3
  6. package/dist/app.js.map +1 -1
  7. package/dist/components/data/index.d.ts +13 -3
  8. package/dist/components/data/index.d.ts.map +1 -1
  9. package/dist/components/data/index.js +38 -16
  10. package/dist/components/data/index.js.map +1 -1
  11. package/dist/components/layout/index.d.ts +36 -1
  12. package/dist/components/layout/index.d.ts.map +1 -1
  13. package/dist/components/layout/index.js +16 -0
  14. package/dist/components/layout/index.js.map +1 -1
  15. package/dist/core/component.d.ts +3 -2
  16. package/dist/core/component.d.ts.map +1 -1
  17. package/dist/core/component.js.map +1 -1
  18. package/dist/index.d.ts +4 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/prefab.css +803 -0
  23. package/dist/renderer/components/data.d.ts.map +1 -1
  24. package/dist/renderer/components/data.js +34 -2
  25. package/dist/renderer/components/data.js.map +1 -1
  26. package/dist/renderer/components/layout.d.ts.map +1 -1
  27. package/dist/renderer/components/layout.js +42 -1
  28. package/dist/renderer/components/layout.js.map +1 -1
  29. package/dist/renderer/rx.d.ts.map +1 -1
  30. package/dist/renderer/rx.js +115 -3
  31. package/dist/renderer/rx.js.map +1 -1
  32. package/dist/renderer/state.d.ts +5 -0
  33. package/dist/renderer/state.d.ts.map +1 -1
  34. package/dist/renderer/state.js +6 -0
  35. package/dist/renderer/state.js.map +1 -1
  36. package/dist/renderer.min.js +30 -30
  37. package/dist/rx/collection.d.ts +92 -0
  38. package/dist/rx/collection.d.ts.map +1 -0
  39. package/dist/rx/collection.js +126 -0
  40. package/dist/rx/collection.js.map +1 -0
  41. package/dist/rx/index.d.ts +6 -0
  42. package/dist/rx/index.d.ts.map +1 -1
  43. package/dist/rx/index.js +4 -0
  44. package/dist/rx/index.js.map +1 -1
  45. package/dist/rx/pipes.d.ts +22 -0
  46. package/dist/rx/pipes.d.ts.map +1 -0
  47. package/dist/rx/pipes.js +32 -0
  48. package/dist/rx/pipes.js.map +1 -0
  49. package/dist/rx/rx.d.ts +7 -1
  50. package/dist/rx/rx.d.ts.map +1 -1
  51. package/dist/rx/rx.js +12 -3
  52. package/dist/rx/rx.js.map +1 -1
  53. package/dist/rx/signal.d.ts +50 -0
  54. package/dist/rx/signal.d.ts.map +1 -0
  55. package/dist/rx/signal.js +58 -0
  56. package/dist/rx/signal.js.map +1 -0
  57. package/dist/rx/state-collector.d.ts +23 -0
  58. package/dist/rx/state-collector.d.ts.map +1 -0
  59. package/dist/rx/state-collector.js +38 -0
  60. package/dist/rx/state-collector.js.map +1 -0
  61. package/package.json +4 -2
@@ -0,0 +1,803 @@
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
+
16
+ :root {
17
+ /* Radii */
18
+ --radius: 8px;
19
+ --radius-sm: 6px;
20
+
21
+ /* Core palette */
22
+ --background: #ffffff;
23
+ --foreground: #09090b;
24
+
25
+ --card: #ffffff;
26
+ --card-foreground: #09090b;
27
+
28
+ --popover: #ffffff;
29
+ --popover-foreground: #09090b;
30
+
31
+ --primary: #3b82f6;
32
+ --primary-foreground: #ffffff;
33
+
34
+ --secondary: #f3f4f6;
35
+ --secondary-foreground: #1f2937;
36
+
37
+ --muted: #f3f4f6;
38
+ --muted-foreground: #6b7280;
39
+
40
+ --accent: #eff6ff;
41
+ --accent-foreground: #1e40af;
42
+
43
+ --destructive: #ef4444;
44
+ --destructive-foreground: #ffffff;
45
+
46
+ --success: #22c55e;
47
+ --success-foreground: #ffffff;
48
+
49
+ --warning: #f59e0b;
50
+ --warning-foreground: #ffffff;
51
+
52
+ --border: #e5e7eb;
53
+ --input: #e5e7eb;
54
+ --ring: #3b82f6;
55
+
56
+ /* Typography */
57
+ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
58
+ Roboto, "Helvetica Neue", Arial, sans-serif;
59
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
60
+ "Liberation Mono", "Courier New", monospace;
61
+ }
62
+
63
+ @media (prefers-color-scheme: dark) {
64
+ :root {
65
+ --background: #09090b;
66
+ --foreground: #fafafa;
67
+
68
+ --card: #111113;
69
+ --card-foreground: #fafafa;
70
+
71
+ --popover: #111113;
72
+ --popover-foreground: #fafafa;
73
+
74
+ --primary: #60a5fa;
75
+ --primary-foreground: #09090b;
76
+
77
+ --secondary: #1f2937;
78
+ --secondary-foreground: #f3f4f6;
79
+
80
+ --muted: #1f2937;
81
+ --muted-foreground: #9ca3af;
82
+
83
+ --accent: #1e3a5f;
84
+ --accent-foreground: #93c5fd;
85
+
86
+ --destructive: #f87171;
87
+ --destructive-foreground: #09090b;
88
+
89
+ --success: #4ade80;
90
+ --success-foreground: #09090b;
91
+
92
+ --warning: #fbbf24;
93
+ --warning-foreground: #09090b;
94
+
95
+ --border: #27272a;
96
+ --input: #27272a;
97
+ --ring: #60a5fa;
98
+ }
99
+ }
100
+
101
+ /* ═══════════════════════════════════════════════════════════════════════════
102
+ 2. RESET & BASE
103
+ ═══════════════════════════════════════════════════════════════════════════ */
104
+
105
+ *, *::before, *::after {
106
+ box-sizing: border-box;
107
+ }
108
+
109
+ .pf-app-root {
110
+ font-family: var(--font-sans);
111
+ color: var(--foreground);
112
+ background-color: var(--background);
113
+ line-height: 1.5;
114
+ -webkit-font-smoothing: antialiased;
115
+ -moz-osx-font-smoothing: grayscale;
116
+ }
117
+
118
+ /* ═══════════════════════════════════════════════════════════════════════════
119
+ 3. LAYOUT
120
+ ═══════════════════════════════════════════════════════════════════════════ */
121
+
122
+ .pf-column { display: flex; flex-direction: column; }
123
+ .pf-row { display: flex; flex-direction: row; flex-wrap: wrap; }
124
+ .pf-grid { display: grid; }
125
+
126
+ .pf-grid-item { min-width: 0; }
127
+ .pf-container { width: 100%; max-width: 1200px; margin: 0 auto; }
128
+ .pf-div { display: block; }
129
+ .pf-span { display: inline; }
130
+ .pf-pages { position: relative; }
131
+
132
+ /* ═══════════════════════════════════════════════════════════════════════════
133
+ 4. TYPOGRAPHY
134
+ ═══════════════════════════════════════════════════════════════════════════ */
135
+
136
+ .pf-heading { margin: 0; font-weight: 600; letter-spacing: -0.02em; }
137
+ .pf-h1 { font-size: 2.25rem; line-height: 2.5rem; }
138
+ .pf-h2 { font-size: 1.875rem; line-height: 2.25rem; }
139
+ .pf-h3 { font-size: 1.5rem; line-height: 2rem; }
140
+ .pf-h4 { font-size: 1.25rem; line-height: 1.75rem; }
141
+
142
+ .pf-text { }
143
+ .pf-p { margin: 0; }
144
+ .pf-lead { font-size: 1.25rem; color: var(--muted-foreground); }
145
+ .pf-large { font-size: 1.125rem; font-weight: 600; }
146
+ .pf-small { font-size: 0.875rem; }
147
+ .pf-muted { color: var(--muted-foreground); font-size: 0.875rem; margin: 0; }
148
+
149
+ .pf-blockquote {
150
+ margin: 0;
151
+ padding-left: 1rem;
152
+ border-left: 3px solid var(--border);
153
+ font-style: italic;
154
+ color: var(--muted-foreground);
155
+ }
156
+
157
+ .pf-label {
158
+ font-size: 0.875rem;
159
+ font-weight: 500;
160
+ }
161
+
162
+ .pf-link {
163
+ color: var(--primary);
164
+ text-decoration: underline;
165
+ text-underline-offset: 4px;
166
+ cursor: pointer;
167
+ }
168
+ .pf-link:hover { text-decoration-thickness: 2px; }
169
+
170
+ .pf-code {
171
+ font-family: var(--font-mono);
172
+ font-size: 0.875rem;
173
+ background: var(--muted);
174
+ border: 1px solid var(--border);
175
+ border-radius: var(--radius-sm);
176
+ padding: 1rem;
177
+ overflow-x: auto;
178
+ margin: 0;
179
+ white-space: pre;
180
+ }
181
+
182
+ .pf-markdown { line-height: 1.7; }
183
+ .pf-markdown h1, .pf-markdown h2, .pf-markdown h3 { margin-top: 1.5em; margin-bottom: 0.5em; }
184
+ .pf-markdown p { margin: 0.75em 0; }
185
+ .pf-markdown code {
186
+ font-family: var(--font-mono);
187
+ font-size: 0.875em;
188
+ background: var(--muted);
189
+ padding: 0.15em 0.4em;
190
+ border-radius: 4px;
191
+ }
192
+ .pf-markdown pre code { background: none; padding: 0; }
193
+
194
+ .pf-kbd {
195
+ display: inline-flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ font-family: var(--font-mono);
199
+ font-size: 0.75rem;
200
+ min-width: 1.5em;
201
+ padding: 0.15em 0.4em;
202
+ border: 1px solid var(--border);
203
+ border-radius: 4px;
204
+ background: var(--muted);
205
+ box-shadow: 0 1px 0 var(--border);
206
+ }
207
+
208
+ /* ═══════════════════════════════════════════════════════════════════════════
209
+ 5. CARD
210
+ ═══════════════════════════════════════════════════════════════════════════ */
211
+
212
+ .pf-card {
213
+ background: var(--card);
214
+ color: var(--card-foreground);
215
+ border: 1px solid var(--border);
216
+ border-radius: var(--radius);
217
+ overflow: hidden;
218
+ }
219
+
220
+ .pf-card-header { padding: 1.5rem 1.5rem 0; }
221
+ .pf-card-content { padding: 1.5rem; }
222
+ .pf-card-footer { padding: 0 1.5rem 1.5rem; display: flex; align-items: center; gap: 0.5rem; }
223
+
224
+ .pf-card-title { margin: 0; font-size: 1.25rem; font-weight: 600; }
225
+ .pf-card-description { margin: 0.25rem 0 0; color: var(--muted-foreground); font-size: 0.875rem; }
226
+
227
+ /* ═══════════════════════════════════════════════════════════════════════════
228
+ 6. ALERT
229
+ ═══════════════════════════════════════════════════════════════════════════ */
230
+
231
+ .pf-alert {
232
+ position: relative;
233
+ padding: 1rem 1rem 1rem 3rem;
234
+ border: 1px solid var(--border);
235
+ border-radius: var(--radius);
236
+ }
237
+ .pf-alert[data-variant="destructive"] {
238
+ border-color: var(--destructive);
239
+ color: var(--destructive);
240
+ }
241
+ .pf-alert-icon {
242
+ position: absolute;
243
+ left: 1rem;
244
+ top: 1rem;
245
+ }
246
+ .pf-alert-title { margin: 0; font-weight: 600; font-size: 0.875rem; }
247
+ .pf-alert-description { margin: 0.25rem 0 0; font-size: 0.875rem; }
248
+
249
+ /* ═══════════════════════════════════════════════════════════════════════════
250
+ 7. BADGE
251
+ ═══════════════════════════════════════════════════════════════════════════ */
252
+
253
+ .pf-badge {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ border-radius: 9999px;
257
+ padding: 0.15em 0.6em;
258
+ font-size: 0.75rem;
259
+ font-weight: 600;
260
+ line-height: 1;
261
+ white-space: nowrap;
262
+ transition: background-color 0.15s;
263
+ }
264
+ .pf-badge[data-variant="default"] { background: var(--primary); color: var(--primary-foreground); }
265
+ .pf-badge[data-variant="secondary"] { background: var(--secondary); color: var(--secondary-foreground); }
266
+ .pf-badge[data-variant="destructive"] { background: var(--destructive); color: var(--destructive-foreground); }
267
+ .pf-badge[data-variant="success"] { background: var(--success); color: var(--success-foreground); }
268
+ .pf-badge[data-variant="warning"] { background: var(--warning); color: var(--warning-foreground); }
269
+ .pf-badge[data-variant="outline"] { background: transparent; border: 1px solid var(--border); color: var(--foreground); }
270
+
271
+ .pf-dot {
272
+ display: inline-block;
273
+ width: 0.5rem;
274
+ height: 0.5rem;
275
+ border-radius: 9999px;
276
+ }
277
+
278
+ /* ═══════════════════════════════════════════════════════════════════════════
279
+ 8. DATA — Metric, Ring, Progress, Separator, Loader, Icon, Sparkline
280
+ ═══════════════════════════════════════════════════════════════════════════ */
281
+
282
+ .pf-metric { display: flex; flex-direction: column; gap: 0.25rem; }
283
+ .pf-metric-label { font-size: 0.875rem; color: var(--muted-foreground); }
284
+ .pf-metric-value { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }
285
+ .pf-metric-delta { font-size: 0.875rem; font-weight: 500; margin-left: 0.5rem; }
286
+ .pf-metric-desc { font-size: 0.75rem; color: var(--muted-foreground); }
287
+
288
+ .pf-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
289
+ .pf-ring-label { position: absolute; text-align: center; font-size: 0.875rem; font-weight: 600; }
290
+
291
+ .pf-progress {
292
+ width: 100%;
293
+ height: 0.5rem;
294
+ background: var(--muted);
295
+ border-radius: 9999px;
296
+ overflow: hidden;
297
+ }
298
+ .pf-progress-fill {
299
+ height: 100%;
300
+ background: var(--primary);
301
+ border-radius: 9999px;
302
+ transition: width 0.3s ease;
303
+ }
304
+
305
+ .pf-separator {
306
+ border: none;
307
+ border-top: 1px solid var(--border);
308
+ margin: 0;
309
+ }
310
+
311
+ .pf-loader {
312
+ display: inline-block;
313
+ width: 1.5rem;
314
+ height: 1.5rem;
315
+ border: 2px solid var(--muted);
316
+ border-top-color: var(--primary);
317
+ border-radius: 50%;
318
+ animation: pf-spin 0.6s linear infinite;
319
+ }
320
+ @keyframes pf-spin { to { transform: rotate(360deg); } }
321
+
322
+ .pf-icon { display: inline-flex; align-items: center; }
323
+
324
+ .pf-sparkline svg { display: block; }
325
+
326
+ /* ═══════════════════════════════════════════════════════════════════════════
327
+ 9. DATATABLE
328
+ ═══════════════════════════════════════════════════════════════════════════ */
329
+
330
+ .pf-datatable-wrapper { overflow-x: auto; }
331
+
332
+ .pf-datatable {
333
+ width: 100%;
334
+ border-collapse: collapse;
335
+ font-size: 0.875rem;
336
+ }
337
+ .pf-datatable-th {
338
+ text-align: left;
339
+ padding: 0.75rem 1rem;
340
+ font-weight: 600;
341
+ border-bottom: 2px solid var(--border);
342
+ white-space: nowrap;
343
+ }
344
+ .pf-datatable-td {
345
+ padding: 0.75rem 1rem;
346
+ border-bottom: 1px solid var(--border);
347
+ }
348
+ .pf-datatable-search {
349
+ width: 100%;
350
+ max-width: 20rem;
351
+ padding: 0.5rem 0.75rem;
352
+ margin-bottom: 0.75rem;
353
+ border: 1px solid var(--input);
354
+ border-radius: var(--radius-sm);
355
+ font-size: 0.875rem;
356
+ background: var(--background);
357
+ color: var(--foreground);
358
+ }
359
+ .pf-datatable-search:focus {
360
+ outline: 2px solid var(--ring);
361
+ outline-offset: -1px;
362
+ }
363
+
364
+ /* ═══════════════════════════════════════════════════════════════════════════
365
+ 10. TABLE (semantic HTML table)
366
+ ═══════════════════════════════════════════════════════════════════════════ */
367
+
368
+ .pf-table {
369
+ width: 100%;
370
+ border-collapse: collapse;
371
+ font-size: 0.875rem;
372
+ }
373
+ .pf-table-row { }
374
+ .pf-table-header {
375
+ text-align: left;
376
+ padding: 0.75rem 1rem;
377
+ font-weight: 600;
378
+ border-bottom: 2px solid var(--border);
379
+ }
380
+ .pf-table-cell {
381
+ padding: 0.75rem 1rem;
382
+ border-bottom: 1px solid var(--border);
383
+ }
384
+ .pf-table-caption {
385
+ caption-side: bottom;
386
+ padding: 0.5rem;
387
+ color: var(--muted-foreground);
388
+ font-size: 0.875rem;
389
+ }
390
+
391
+ .pf-expandable-row { }
392
+ .pf-expandable-row-summary {
393
+ display: flex;
394
+ align-items: center;
395
+ gap: 0.5rem;
396
+ cursor: pointer;
397
+ user-select: none;
398
+ }
399
+ .pf-expandable-arrow {
400
+ display: inline-block;
401
+ transition: transform 0.2s;
402
+ }
403
+ .pf-expandable-row-detail {
404
+ padding-left: 1.5rem;
405
+ }
406
+
407
+ /* ═══════════════════════════════════════════════════════════════════════════
408
+ 11. FORM
409
+ ═══════════════════════════════════════════════════════════════════════════ */
410
+
411
+ .pf-form { display: flex; flex-direction: column; gap: 1rem; }
412
+
413
+ .pf-input-wrapper, .pf-textarea-wrapper, .pf-select-wrapper, .pf-slider-wrapper {
414
+ display: flex;
415
+ flex-direction: column;
416
+ gap: 0.375rem;
417
+ }
418
+
419
+ .pf-input-label {
420
+ font-size: 0.875rem;
421
+ font-weight: 500;
422
+ }
423
+
424
+ .pf-input, .pf-textarea, .pf-select {
425
+ padding: 0.5rem 0.75rem;
426
+ border: 1px solid var(--input);
427
+ border-radius: var(--radius-sm);
428
+ font-size: 0.875rem;
429
+ background: var(--background);
430
+ color: var(--foreground);
431
+ transition: border-color 0.15s, box-shadow 0.15s;
432
+ }
433
+ .pf-input:focus, .pf-textarea:focus, .pf-select:focus {
434
+ outline: 2px solid var(--ring);
435
+ outline-offset: -1px;
436
+ border-color: var(--ring);
437
+ }
438
+ .pf-textarea { min-height: 5rem; resize: vertical; }
439
+
440
+ /* Buttons */
441
+ .pf-button {
442
+ display: inline-flex;
443
+ align-items: center;
444
+ justify-content: center;
445
+ gap: 0.5rem;
446
+ padding: 0.5rem 1rem;
447
+ border: none;
448
+ border-radius: var(--radius-sm);
449
+ font-size: 0.875rem;
450
+ font-weight: 500;
451
+ cursor: pointer;
452
+ transition: opacity 0.15s, background-color 0.15s;
453
+ white-space: nowrap;
454
+ }
455
+ .pf-button:hover { opacity: 0.9; }
456
+ .pf-button:active { opacity: 0.8; }
457
+ .pf-button:disabled { opacity: 0.5; cursor: not-allowed; }
458
+
459
+ .pf-button[data-variant="default"] { background: var(--primary); color: var(--primary-foreground); }
460
+ .pf-button[data-variant="secondary"] { background: var(--secondary); color: var(--secondary-foreground); }
461
+ .pf-button[data-variant="destructive"] { background: var(--destructive); color: var(--destructive-foreground); }
462
+ .pf-button[data-variant="ghost"] { background: transparent; color: var(--foreground); }
463
+ .pf-button[data-variant="ghost"]:hover { background: var(--accent); }
464
+ .pf-button[data-variant="outline"] { background: transparent; color: var(--foreground); border: 1px solid var(--border); }
465
+ .pf-button[data-variant="outline"]:hover { background: var(--accent); }
466
+ .pf-button[data-variant="link"] { background: transparent; color: var(--primary); text-decoration: underline; padding: 0; }
467
+
468
+ .pf-button-group { display: flex; gap: 0.5rem; flex-wrap: wrap; }
469
+
470
+ /* Checkbox, Switch, Slider, Radio */
471
+ .pf-checkbox-wrapper, .pf-switch-wrapper {
472
+ display: flex;
473
+ align-items: center;
474
+ gap: 0.5rem;
475
+ cursor: pointer;
476
+ }
477
+ .pf-checkbox, .pf-switch { accent-color: var(--primary); }
478
+
479
+ .pf-slider { width: 100%; accent-color: var(--primary); }
480
+
481
+ .pf-radio {
482
+ display: flex;
483
+ align-items: center;
484
+ gap: 0.5rem;
485
+ cursor: pointer;
486
+ }
487
+ .pf-radio-label { font-size: 0.875rem; }
488
+ .pf-radio-group {
489
+ border: none;
490
+ padding: 0;
491
+ margin: 0;
492
+ display: flex;
493
+ flex-direction: column;
494
+ gap: 0.5rem;
495
+ }
496
+
497
+ /* Select separator */
498
+ .pf-select-group { }
499
+ .pf-select-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.25rem 0; }
500
+
501
+ /* Field */
502
+ .pf-field {
503
+ display: flex;
504
+ flex-direction: column;
505
+ gap: 0.375rem;
506
+ }
507
+ .pf-field-title { font-size: 0.875rem; font-weight: 500; }
508
+ .pf-field-description { font-size: 0.75rem; color: var(--muted-foreground); }
509
+ .pf-field-content { }
510
+ .pf-field-error { font-size: 0.75rem; color: var(--destructive); }
511
+
512
+ /* Combobox */
513
+ .pf-combobox { position: relative; }
514
+ .pf-combobox-input {
515
+ width: 100%;
516
+ padding: 0.5rem 0.75rem;
517
+ border: 1px solid var(--input);
518
+ border-radius: var(--radius-sm);
519
+ font-size: 0.875rem;
520
+ background: var(--background);
521
+ color: var(--foreground);
522
+ }
523
+ .pf-combobox-input:focus {
524
+ outline: 2px solid var(--ring);
525
+ outline-offset: -1px;
526
+ }
527
+ .pf-combobox-dropdown {
528
+ position: absolute;
529
+ top: 100%;
530
+ left: 0;
531
+ right: 0;
532
+ z-index: 50;
533
+ margin-top: 0.25rem;
534
+ background: var(--popover);
535
+ color: var(--popover-foreground);
536
+ border: 1px solid var(--border);
537
+ border-radius: var(--radius-sm);
538
+ box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
539
+ max-height: 15rem;
540
+ overflow-y: auto;
541
+ }
542
+ .pf-combobox-option {
543
+ padding: 0.5rem 0.75rem;
544
+ cursor: pointer;
545
+ font-size: 0.875rem;
546
+ }
547
+ .pf-combobox-option:hover { background: var(--accent); }
548
+ .pf-combobox-group { }
549
+ .pf-combobox-label { font-size: 0.75rem; color: var(--muted-foreground); font-weight: 600; padding: 0.5rem 0.75rem 0.25rem; }
550
+
551
+ /* Calendar & DatePicker */
552
+ .pf-calendar {
553
+ border: 1px solid var(--border);
554
+ border-radius: var(--radius-sm);
555
+ padding: 0.75rem;
556
+ font-size: 0.875rem;
557
+ }
558
+ .pf-datepicker {
559
+ display: flex;
560
+ flex-direction: column;
561
+ gap: 0.375rem;
562
+ }
563
+
564
+ /* ChoiceCard */
565
+ .pf-choice-card {
566
+ border: 2px solid var(--border);
567
+ border-radius: var(--radius);
568
+ padding: 1rem;
569
+ cursor: pointer;
570
+ transition: border-color 0.15s, background-color 0.15s;
571
+ }
572
+ .pf-choice-card:hover { border-color: var(--ring); }
573
+ .pf-choice-card-label { font-weight: 500; }
574
+ .pf-choice-card-description { font-size: 0.875rem; color: var(--muted-foreground); margin-top: 0.25rem; }
575
+
576
+ /* ═══════════════════════════════════════════════════════════════════════════
577
+ 12. TABS
578
+ ═══════════════════════════════════════════════════════════════════════════ */
579
+
580
+ .pf-tabs { }
581
+ .pf-tabs-bar {
582
+ display: flex;
583
+ gap: 0;
584
+ border-bottom: 1px solid var(--border);
585
+ margin-bottom: 1rem;
586
+ }
587
+ .pf-tab-trigger {
588
+ padding: 0.5rem 1rem;
589
+ font-size: 0.875rem;
590
+ font-weight: 500;
591
+ cursor: pointer;
592
+ background: transparent;
593
+ border: none;
594
+ border-bottom: 2px solid transparent;
595
+ color: var(--muted-foreground);
596
+ transition: color 0.15s, border-color 0.15s;
597
+ }
598
+ .pf-tab-trigger:hover { color: var(--foreground); }
599
+ .pf-tab-trigger[aria-selected="true"] {
600
+ color: var(--foreground);
601
+ border-bottom-color: var(--primary);
602
+ }
603
+ .pf-tab-panel { }
604
+ .pf-tab { }
605
+
606
+ /* ═══════════════════════════════════════════════════════════════════════════
607
+ 13. ACCORDION
608
+ ═══════════════════════════════════════════════════════════════════════════ */
609
+
610
+ .pf-accordion { display: flex; flex-direction: column; }
611
+ .pf-accordion-item { border-bottom: 1px solid var(--border); }
612
+ .pf-accordion-trigger {
613
+ display: flex;
614
+ align-items: center;
615
+ justify-content: space-between;
616
+ width: 100%;
617
+ padding: 1rem 0;
618
+ font-size: 0.875rem;
619
+ font-weight: 500;
620
+ cursor: pointer;
621
+ background: transparent;
622
+ border: none;
623
+ text-align: left;
624
+ color: var(--foreground);
625
+ }
626
+ .pf-accordion-trigger:hover { text-decoration: underline; }
627
+ .pf-accordion-content { padding-bottom: 1rem; }
628
+
629
+ /* ═══════════════════════════════════════════════════════════════════════════
630
+ 14. DIALOG
631
+ ═══════════════════════════════════════════════════════════════════════════ */
632
+
633
+ .pf-dialog-wrapper { }
634
+ .pf-dialog {
635
+ background: var(--card);
636
+ color: var(--card-foreground);
637
+ border: 1px solid var(--border);
638
+ border-radius: var(--radius);
639
+ padding: 1.5rem;
640
+ max-width: 32rem;
641
+ width: 90vw;
642
+ }
643
+ .pf-dialog::backdrop {
644
+ background: rgba(0, 0, 0, 0.5);
645
+ }
646
+ .pf-dialog-title { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 600; }
647
+ .pf-dialog-desc { margin: 0 0 1rem; color: var(--muted-foreground); font-size: 0.875rem; }
648
+ .pf-dialog-body { }
649
+
650
+ /* ═══════════════════════════════════════════════════════════════════════════
651
+ 15. POPOVER, TOOLTIP, HOVER CARD
652
+ ═══════════════════════════════════════════════════════════════════════════ */
653
+
654
+ .pf-popover { position: relative; display: inline-block; }
655
+ .pf-popover-content {
656
+ position: absolute;
657
+ z-index: 50;
658
+ min-width: 12rem;
659
+ padding: 1rem;
660
+ background: var(--popover);
661
+ color: var(--popover-foreground);
662
+ border: 1px solid var(--border);
663
+ border-radius: var(--radius);
664
+ box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
665
+ }
666
+ .pf-popover-title { font-weight: 600; margin-bottom: 0.5rem; }
667
+
668
+ .pf-tooltip { position: relative; display: inline-block; }
669
+ .pf-tooltip-content {
670
+ position: absolute;
671
+ z-index: 50;
672
+ bottom: 100%;
673
+ left: 50%;
674
+ transform: translateX(-50%);
675
+ margin-bottom: 0.5rem;
676
+ padding: 0.375rem 0.75rem;
677
+ background: var(--foreground);
678
+ color: var(--background);
679
+ border-radius: var(--radius-sm);
680
+ font-size: 0.75rem;
681
+ white-space: nowrap;
682
+ pointer-events: none;
683
+ }
684
+
685
+ .pf-hover-card { position: relative; display: inline-block; }
686
+ .pf-hover-card-content {
687
+ position: absolute;
688
+ z-index: 50;
689
+ min-width: 16rem;
690
+ padding: 1rem;
691
+ background: var(--card);
692
+ color: var(--card-foreground);
693
+ border: 1px solid var(--border);
694
+ border-radius: var(--radius);
695
+ box-shadow: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);
696
+ }
697
+
698
+ /* ═══════════════════════════════════════════════════════════════════════════
699
+ 16. CAROUSEL
700
+ ═══════════════════════════════════════════════════════════════════════════ */
701
+
702
+ .pf-carousel { position: relative; overflow: hidden; }
703
+ .pf-carousel-track {
704
+ display: flex;
705
+ transition: transform 0.3s ease;
706
+ }
707
+ .pf-carousel-track > * { flex: 0 0 100%; min-width: 0; }
708
+
709
+ .pf-carousel-prev,
710
+ .pf-carousel-next {
711
+ position: absolute;
712
+ top: 50%;
713
+ transform: translateY(-50%);
714
+ z-index: 10;
715
+ width: 2rem;
716
+ height: 2rem;
717
+ display: flex;
718
+ align-items: center;
719
+ justify-content: center;
720
+ border-radius: 50%;
721
+ border: 1px solid var(--border);
722
+ background: var(--card);
723
+ color: var(--foreground);
724
+ cursor: pointer;
725
+ font-size: 1rem;
726
+ }
727
+ .pf-carousel-prev { left: 0.5rem; }
728
+ .pf-carousel-next { right: 0.5rem; }
729
+ .pf-carousel-prev:hover,
730
+ .pf-carousel-next:hover { background: var(--accent); }
731
+
732
+ /* ═══════════════════════════════════════════════════════════════════════════
733
+ 17. CHARTS
734
+ ═══════════════════════════════════════════════════════════════════════════ */
735
+
736
+ .pf-chart { position: relative; }
737
+ .pf-chart svg { display: block; width: 100%; height: auto; }
738
+
739
+ .pf-chart-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.75rem; font-size: 0.75rem; }
740
+ .pf-chart-legend-item { display: flex; align-items: center; gap: 0.375rem; }
741
+
742
+ /* ═══════════════════════════════════════════════════════════════════════════
743
+ 18. MEDIA
744
+ ═══════════════════════════════════════════════════════════════════════════ */
745
+
746
+ .pf-image { max-width: 100%; height: auto; display: block; }
747
+ .pf-audio { width: 100%; }
748
+ .pf-video { max-width: 100%; height: auto; display: block; }
749
+ .pf-embed { position: relative; overflow: hidden; }
750
+ .pf-embed iframe { border: none; }
751
+ .pf-svg { display: inline-block; }
752
+ .pf-mermaid { overflow-x: auto; }
753
+
754
+ .pf-dropzone {
755
+ border: 2px dashed var(--border);
756
+ border-radius: var(--radius);
757
+ padding: 2rem;
758
+ text-align: center;
759
+ color: var(--muted-foreground);
760
+ cursor: pointer;
761
+ transition: border-color 0.15s;
762
+ }
763
+ .pf-dropzone:hover, .pf-dropzone.pf-dropzone--active {
764
+ border-color: var(--primary);
765
+ }
766
+
767
+ /* ═══════════════════════════════════════════════════════════════════════════
768
+ 19. TOAST
769
+ ═══════════════════════════════════════════════════════════════════════════ */
770
+
771
+ .pf-toast {
772
+ background: var(--card);
773
+ color: var(--card-foreground);
774
+ border: 1px solid var(--border);
775
+ border-radius: var(--radius);
776
+ padding: 1rem;
777
+ box-shadow: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);
778
+ max-width: 24rem;
779
+ }
780
+
781
+ /* ═══════════════════════════════════════════════════════════════════════════
782
+ 20. UTILITY — Tailwind-style gap/padding helpers used in cssClass
783
+ ═══════════════════════════════════════════════════════════════════════════ */
784
+
785
+ .gap-0 { gap: 0; } .gap-1 { gap: 0.25rem; } .gap-2 { gap: 0.5rem; }
786
+ .gap-3 { gap: 0.75rem;} .gap-4 { gap: 1rem; } .gap-5 { gap: 1.25rem; }
787
+ .gap-6 { gap: 1.5rem; } .gap-8 { gap: 2rem; } .gap-10 { gap: 2.5rem; }
788
+
789
+ .p-0 { padding: 0; } .p-1 { padding: 0.25rem; } .p-2 { padding: 0.5rem; }
790
+ .p-3 { padding: 0.75rem;} .p-4 { padding: 1rem; } .p-5 { padding: 1.25rem; }
791
+ .p-6 { padding: 1.5rem; } .p-8 { padding: 2rem; } .p-10 { padding: 2.5rem; }
792
+
793
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
794
+ .py-4 { padding-top: 1rem; padding-bottom: 1rem; }
795
+
796
+ .w-40 { width: 10rem; }
797
+ .max-w-2xl { max-width: 42rem; }
798
+
799
+ .shrink-0 { flex-shrink: 0; }
800
+ .font-medium { font-weight: 500; }
801
+ .font-semibold { font-weight: 600; }
802
+ .tabular-nums { font-variant-numeric: tabular-nums; }
803
+ .text-muted-foreground { color: var(--muted-foreground); }