@blurrow/ui 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,401 @@
1
+ /* blurrow/ui: design tokens, materials and keyframes.
2
+ Import after tailwindcss: @import "tailwindcss"; @import "@blurrow/ui/styles.css";
3
+ The kit is set in Archivo; load it as the --font-archivo variable. */
4
+
5
+ @theme {
6
+ --font-sans: var(--font-archivo), ui-sans-serif, system-ui, sans-serif;
7
+ }
8
+
9
+ /* ── Material tokens ─────────────────────────────────────────────── */
10
+ /* One light source from above: highlights live on top edges, shade on
11
+ bottom edges, and every raised face casts onto whatever holds it. */
12
+ :root {
13
+ --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
14
+ --ease-out-soft: cubic-bezier(0.16, 1, 0.3, 1);
15
+
16
+ /* Light material */
17
+ --bezel-light: linear-gradient(180deg, #f7f7f7 0%, #dedede 100%);
18
+ --bezel-light-shadow:
19
+ 0 0 0 0.5px rgba(17, 17, 17, 0.054), 0 1px 1px rgba(17, 17, 17, 0.06),
20
+ 0 4px 10px -4px rgba(17, 17, 17, 0.14), inset 0 2px 3px -2px rgba(255, 255, 255, 1),
21
+ inset 0 -2px 3px -2px rgba(17, 17, 17, 0.04);
22
+ --face-light: linear-gradient(180deg, #ffffff 0%, #fafafa 55%, #f3f3f3 100%);
23
+ --face-light-shadow:
24
+ 0 0 3px rgba(17, 17, 17, 0.119),
25
+ 0 1px 4px -1px rgba(17, 17, 17, 0.1), inset 0 2px 3px -2px rgba(255, 255, 255, 1),
26
+ inset 0 -2px 3px -2px rgba(17, 17, 17, 0.035);
27
+
28
+ /* Dark material */
29
+ --bezel-dark: linear-gradient(180deg, #2c2c2c 0%, #0c0c0c 100%);
30
+ --bezel-dark-shadow:
31
+ 0 0 0 0.5px rgba(0, 0, 0, 0.33), 0 1px 1px rgba(0, 0, 0, 0.2),
32
+ 0 4px 12px -4px rgba(0, 0, 0, 0.45), inset 0 2px 3px -2px rgba(255, 255, 255, 0.075);
33
+ --face-dark: linear-gradient(180deg, #2e2e2e 0%, #1f1f1f 55%, #181818 100%);
34
+ --face-dark-shadow:
35
+ 0 0 3px rgba(0, 0, 0, 0.35),
36
+ 0 1px 4px -1px rgba(0, 0, 0, 0.3), inset 0 2px 3px -2px rgba(255, 255, 255, 0.105),
37
+ inset 0 -2px 3px -2px rgba(0, 0, 0, 0.25);
38
+
39
+ /* Sunken face (pressed) — the face drops flush with its bezel */
40
+ --face-light-pressed:
41
+ 0 0 3px rgba(17, 17, 17, 0.136), inset 0 1px 2px rgba(17, 17, 17, 0.08);
42
+ --face-dark-pressed:
43
+ 0 0 3px rgba(0, 0, 0, 0.35), inset 0 1px 2px rgba(0, 0, 0, 0.45);
44
+
45
+ /* Fields — sunken: darker at the top, shade inside, a lit lip below.
46
+ Raised means "press me", sunken means "fill me".
47
+
48
+ Every state has the same five layers (edge, shade, lip, border, halo)
49
+ so box-shadow interpolates between them instead of snapping: hover
50
+ hints at the halo, focus lifts the well flush and draws the border. */
51
+ --field: linear-gradient(180deg, #f2f2f2 0%, #f8f8f8 100%);
52
+ --field-hover: linear-gradient(180deg, #eeeeee 0%, #f5f5f5 100%);
53
+ --field-shadow:
54
+ inset 0 0 2px rgba(17, 17, 17, 0.15), inset 0 1px 2px rgba(17, 17, 17, 0.06),
55
+ 0 1px 2px -1px rgba(255, 255, 255, 0.72), inset 0 0 0 1px rgba(17, 17, 17, 0),
56
+ 0 0 0 0 rgba(17, 17, 17, 0);
57
+ --field-shadow-hover:
58
+ inset 0 0 2px rgba(17, 17, 17, 0.25), inset 0 1px 2px rgba(17, 17, 17, 0.07),
59
+ 0 1px 2px -1px rgba(255, 255, 255, 0.72), inset 0 0 0 1px rgba(17, 17, 17, 0.04),
60
+ 0 0 0 3px rgba(17, 17, 17, 0.025);
61
+ --field-shadow-focus:
62
+ inset 0 0 2px rgba(17, 17, 17, 0.06), inset 0 1px 2px rgba(17, 17, 17, 0.02),
63
+ 0 1px 2px -1px rgba(255, 255, 255, 0), inset 0 0 0 1px rgba(17, 17, 17, 0.42),
64
+ 0 0 0 4px rgba(17, 17, 17, 0.07);
65
+ --field-shadow-error:
66
+ inset 0 0 2px rgba(220, 38, 38, 0.3), inset 0 1px 2px rgba(220, 38, 38, 0.06),
67
+ 0 1px 2px -1px rgba(255, 255, 255, 0.72), inset 0 0 0 1px rgba(220, 38, 38, 0),
68
+ 0 0 0 0 rgba(220, 38, 38, 0);
69
+ --field-shadow-error-hover:
70
+ inset 0 0 2px rgba(220, 38, 38, 0.4), inset 0 1px 2px rgba(220, 38, 38, 0.08),
71
+ 0 1px 2px -1px rgba(255, 255, 255, 0.72), inset 0 0 0 1px rgba(220, 38, 38, 0.08),
72
+ 0 0 0 3px rgba(220, 38, 38, 0.04);
73
+ --field-shadow-error-focus:
74
+ inset 0 0 2px rgba(220, 38, 38, 0.1), inset 0 1px 2px rgba(220, 38, 38, 0.02),
75
+ 0 1px 2px -1px rgba(255, 255, 255, 0), inset 0 0 0 1px rgba(220, 38, 38, 0.7),
76
+ 0 0 0 4px rgba(220, 38, 38, 0.1);
77
+
78
+ /* Wells hold a sliding thumb (tabs, pagination, segmented controls) */
79
+ --well: linear-gradient(180deg, #ebebeb 0%, #f1f1f1 100%);
80
+ --well-shadow:
81
+ inset 0 0 2px rgba(17, 17, 17, 0.09), inset 0 1px 2px rgba(17, 17, 17, 0.08),
82
+ 0 1px 2px -1px rgba(255, 255, 255, 0.72);
83
+ --thumb-shadow:
84
+ 0 0 3px rgba(17, 17, 17, 0.102), 0 1px 2px rgba(17, 17, 17, 0.1),
85
+ 0 2px 6px -2px rgba(17, 17, 17, 0.08), inset 0 2px 3px -2px rgba(255, 255, 255, 1);
86
+
87
+ /* Panels — a soft bezel holding a white face (lists, menus, alerts) */
88
+ --panel-bezel: linear-gradient(180deg, #fbfbfb 0%, #f0f0f0 100%);
89
+ --panel-shadow:
90
+ 0 0 0 0.5px rgba(17, 17, 17, 0.036), 0 1px 2px rgba(17, 17, 17, 0.04),
91
+ 0 4px 12px -4px rgba(17, 17, 17, 0.08), inset 0 2px 3px -2px rgba(255, 255, 255, 1);
92
+ --panel-face-shadow:
93
+ 0 0 3px rgba(17, 17, 17, 0.076), 0 1px 2px rgba(17, 17, 17, 0.05),
94
+ inset 0 2px 3px -2px rgba(255, 255, 255, 1);
95
+ /* Panels that float above the page cast further */
96
+ --overlay-shadow:
97
+ 0 0 0 0.5px rgba(17, 17, 17, 0.048), 0 4px 12px -4px rgba(17, 17, 17, 0.12),
98
+ 0 16px 40px -12px rgba(17, 17, 17, 0.2), inset 0 2px 3px -2px rgba(255, 255, 255, 1);
99
+ --modal-shadow:
100
+ 0 0 0 0.5px rgba(17, 17, 17, 0.048), 0 8px 24px -8px rgba(17, 17, 17, 0.2),
101
+ 0 32px 80px -16px rgba(17, 17, 17, 0.32), inset 0 2px 3px -2px rgba(255, 255, 255, 1);
102
+ --scrim: rgba(10, 10, 10, 0.4);
103
+
104
+ /* Cards — the largest surfaces; pair with .rim */
105
+ --card-light: linear-gradient(180deg, #ffffff 0%, #fefefe 40%, #fafafa 100%);
106
+ --card-light-shadow:
107
+ 0 1px 3px rgba(17, 17, 17, 0.02), 0 4px 12px -2px rgba(17, 17, 17, 0.05),
108
+ 0 8px 24px -4px rgba(17, 17, 17, 0.04), 0 0 0 0.5px rgba(17, 17, 17, 0.036),
109
+ inset 0 2.5px 3px -2px rgba(255, 255, 255, 0.712);
110
+ --card-light-shadow-hover:
111
+ 0 2px 6px rgba(17, 17, 17, 0.03), 0 8px 24px -4px rgba(17, 17, 17, 0.08),
112
+ 0 16px 48px -8px rgba(17, 17, 17, 0.1), 0 32px 96px -16px rgba(17, 17, 17, 0.08),
113
+ 0 0 0 0.5px rgba(17, 17, 17, 0.048), inset 0 3px 3px -2px rgba(255, 255, 255, 1);
114
+ --card-dark:
115
+ radial-gradient(90% 60% at 50% 0%, rgba(255, 255, 255, 0.06), transparent 75%),
116
+ radial-gradient(140% 100% at 30% 0%, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 65%),
117
+ linear-gradient(180deg, #121212 0%, #0a0a0a 100%);
118
+ /* Same lift as the light card — only the material changes, not the height */
119
+ --card-dark-shadow:
120
+ 0 0 0 0.5px rgba(0, 0, 0, 0.33), 0 1px 3px rgba(17, 17, 17, 0.12),
121
+ 0 4px 12px -2px rgba(17, 17, 17, 0.14), 0 12px 28px -8px rgba(17, 17, 17, 0.2),
122
+ inset 0 2px 3px -2px rgba(255, 255, 255, 0.075);
123
+ --card-dark-shadow-hover:
124
+ 0 0 0 0.5px rgba(0, 0, 0, 0.54), 0 2px 6px rgba(17, 17, 17, 0.14),
125
+ 0 10px 28px -6px rgba(17, 17, 17, 0.22), 0 28px 64px -16px rgba(17, 17, 17, 0.22),
126
+ inset 0 2px 3px -2px rgba(255, 255, 255, 0.09);
127
+
128
+ /* Card chassis is nearly the face's own tone — the hairline separator
129
+ between them does the dividing, not a change of colour. */
130
+ --card-bezel-light: linear-gradient(180deg, #fdfdfd 0%, #f7f7f7 100%);
131
+ --card-face-light-shadow:
132
+ 0 0 0 0.5px rgba(17, 17, 17, 0.042), 0 1px 2px rgba(17, 17, 17, 0.04),
133
+ inset 0 2px 3px -2px rgba(255, 255, 255, 1);
134
+ --card-bezel-dark: linear-gradient(180deg, #151515 0%, #0e0e0e 100%);
135
+ --card-face-dark-shadow:
136
+ 0 0 0 0.5px rgba(255, 255, 255, 0.042), 0 1px 2px rgba(0, 0, 0, 0.4),
137
+ inset 0 2px 3px -2px rgba(255, 255, 255, 0.045);
138
+
139
+ /* Empty media slots: a whisper darker than the face they sit in */
140
+ --media-well-light: linear-gradient(180deg, rgba(17, 17, 17, 0.025) 0%, rgba(17, 17, 17, 0.04) 100%);
141
+ --media-well-dark: linear-gradient(180deg, rgba(0, 0, 0, 0.18) 0%, rgba(0, 0, 0, 0.26) 100%);
142
+
143
+ /* Icon tiles on cards — small raised faces */
144
+ --tile-light-shadow:
145
+ 0 0 3px rgba(17, 17, 17, 0.102), 0 1px 2px rgba(17, 17, 17, 0.08),
146
+ inset 0 2px 3px -2px rgba(255, 255, 255, 1);
147
+ --tile-dark: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.04) 100%);
148
+ --tile-dark-shadow:
149
+ 0 0 0 0.5px rgba(255, 255, 255, 0.048), 0 2px 6px rgba(0, 0, 0, 0.35),
150
+ inset 0 2px 3px -2px rgba(255, 255, 255, 0.09);
151
+ }
152
+
153
+ /* ── Scrollbars inside panels ────────────────────────────────────── */
154
+ .scroll-thin {
155
+ scrollbar-width: thin;
156
+ scrollbar-color: rgba(17, 17, 17, 0.15) transparent;
157
+ }
158
+
159
+ /* ── Rim light ───────────────────────────────────────────────────── */
160
+ /* A hairline border that is bright at the top and fades by the middle,
161
+ like light catching the edge of a surface. Set --rim to tune it. */
162
+ .rim {
163
+ position: relative;
164
+ }
165
+ .rim::before {
166
+ content: '';
167
+ position: absolute;
168
+ inset: 0;
169
+ border-radius: inherit;
170
+ padding: 1px;
171
+ background: linear-gradient(180deg, var(--rim, rgba(255, 255, 255, 0.9)) 0%, transparent 55%);
172
+ -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
173
+ -webkit-mask-composite: xor;
174
+ mask-composite: exclude;
175
+ pointer-events: none;
176
+ z-index: 1;
177
+ }
178
+
179
+ /* ── Field ───────────────────────────────────────────────────────── */
180
+ /* Gradients can't transition, but registered colours can — so the well's
181
+ two stops are animatable properties and focus fades it up to white
182
+ rather than swapping it in a single frame. */
183
+ @property --field-top {
184
+ syntax: '<color>';
185
+ inherits: false;
186
+ initial-value: #f2f2f2;
187
+ }
188
+ @property --field-bottom {
189
+ syntax: '<color>';
190
+ inherits: false;
191
+ initial-value: #f8f8f8;
192
+ }
193
+ @layer components {
194
+ .field {
195
+ --field-top: #f2f2f2;
196
+ --field-bottom: #f8f8f8;
197
+ background: linear-gradient(180deg, var(--field-top) 0%, var(--field-bottom) 100%);
198
+ box-shadow: var(--field-shadow);
199
+ transition:
200
+ --field-top 260ms var(--ease-out-soft),
201
+ --field-bottom 260ms var(--ease-out-soft),
202
+ box-shadow 260ms var(--ease-out-soft);
203
+ }
204
+ .field:hover {
205
+ --field-top: #eeeeee;
206
+ --field-bottom: #f5f5f5;
207
+ box-shadow: var(--field-shadow-hover);
208
+ }
209
+ .field:focus-visible,
210
+ .field:is(input, textarea):focus,
211
+ .field[data-open] {
212
+ --field-top: #ffffff;
213
+ --field-bottom: #ffffff;
214
+ outline: none;
215
+ box-shadow: var(--field-shadow-focus);
216
+ }
217
+ .field[aria-invalid='true'] {
218
+ box-shadow: var(--field-shadow-error);
219
+ }
220
+ .field[aria-invalid='true']:hover {
221
+ box-shadow: var(--field-shadow-error-hover);
222
+ }
223
+ .field[aria-invalid='true']:focus {
224
+ box-shadow: var(--field-shadow-error-focus);
225
+ }
226
+ }
227
+
228
+ /* ── Button ──────────────────────────────────────────────────────── */
229
+ /* Trailing icons lean toward where the button is taking you. */
230
+ .btn-icon-nudge > svg:last-child:not(:first-child) {
231
+ transition: transform 320ms var(--ease-spring);
232
+ }
233
+ [data-btn]:hover .btn-icon-nudge > svg:last-child:not(:first-child) {
234
+ transform: translateX(2px);
235
+ }
236
+
237
+ /* Motion is decoration; when someone asks for less, every component
238
+ still lands in its final state, just without the journey. */
239
+ @media (prefers-reduced-motion: reduce) {
240
+ *,
241
+ *::before,
242
+ *::after {
243
+ animation-duration: 1ms !important;
244
+ animation-iteration-count: 1 !important;
245
+ transition-duration: 1ms !important;
246
+ }
247
+ }
248
+
249
+ /* ── Carousel ────────────────────────────────────────────────────── */
250
+ @keyframes carousel-progress {
251
+ from { transform: scaleX(0); }
252
+ to { transform: scaleX(1); }
253
+ }
254
+ .carousel-progress { animation: carousel-progress linear both; }
255
+
256
+ /* ── Checkbox / Radio mark ──────────────────────────────────── */
257
+ @keyframes checkbox-in {
258
+ 0% { transform: scale(0); opacity: 0; }
259
+ 55% { transform: scale(1.25); opacity: 1; }
260
+ 100% { transform: scale(1); opacity: 1; }
261
+ }
262
+ .animate-checkbox-in {
263
+ animation: checkbox-in 220ms cubic-bezier(0.34, 1.2, 0.64, 1) both;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ }
268
+
269
+ @keyframes draw-checkmark {
270
+ from { stroke-dashoffset: 15; }
271
+ to { stroke-dashoffset: 0; }
272
+ }
273
+ .animate-draw-check {
274
+ stroke-dasharray: 15;
275
+ stroke-dashoffset: 15;
276
+ animation: draw-checkmark 200ms cubic-bezier(0.65, 0, 0.35, 1) 80ms both;
277
+ }
278
+
279
+ /* ── Tab panel ───────────────────────────────────────────────────── */
280
+ @keyframes tab-slide-right {
281
+ from { opacity: 0; transform: translateX(20px); }
282
+ to { opacity: 1; transform: translateX(0); }
283
+ }
284
+ @keyframes tab-slide-left {
285
+ from { opacity: 0; transform: translateX(-20px); }
286
+ to { opacity: 1; transform: translateX(0); }
287
+ }
288
+ .animate-tab-slide-right {
289
+ animation: tab-slide-right 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
290
+ }
291
+ .animate-tab-slide-left {
292
+ animation: tab-slide-left 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
293
+ }
294
+
295
+ /* ── Modal ───────────────────────────────────────────────────────── */
296
+ @keyframes modal-in {
297
+ from { opacity: 0; transform: scale(0.94) translateY(12px); }
298
+ to { opacity: 1; transform: scale(1) translateY(0); }
299
+ }
300
+ @keyframes modal-out {
301
+ from { opacity: 1; transform: scale(1) translateY(0); }
302
+ to { opacity: 0; transform: scale(0.96) translateY(8px); }
303
+ }
304
+ .animate-modal-in { animation: modal-in 300ms cubic-bezier(0.34,1.4,0.64,1) both; }
305
+ .animate-modal-out { animation: modal-out 220ms ease-in both; }
306
+
307
+ @keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }
308
+ @keyframes backdrop-out { from { opacity: 1; } to { opacity: 0; } }
309
+ .animate-backdrop-in { animation: backdrop-in 260ms ease-out both; }
310
+ .animate-backdrop-out { animation: backdrop-out 220ms ease-in both; }
311
+
312
+ /* ── Tooltip (handled via inline transitions) ────────────────────── */
313
+
314
+ /* ── Input / Select shimmer sweep ────────────────────────────────── */
315
+ @keyframes input-shimmer {
316
+ 0% { transform: translateX(0%); opacity: 0; }
317
+ 12% { opacity: 1; }
318
+ 88% { opacity: 1; }
319
+ 100% { transform: translateX(420%); opacity: 0; }
320
+ }
321
+ .animate-input-shimmer {
322
+ animation: input-shimmer 850ms cubic-bezier(0.4, 0, 0.2, 1) both;
323
+ }
324
+
325
+ @keyframes select-in {
326
+ from { opacity: 0; transform: scale(0.97) translateY(-4px); }
327
+ to { opacity: 1; transform: scale(1) translateY(0); }
328
+ }
329
+
330
+ @keyframes select-option-in {
331
+ from { opacity: 0; transform: translateY(-3px); }
332
+ to { opacity: 1; transform: translateY(0); }
333
+ }
334
+
335
+ /* ── Pagination number shift ─────────────────────────────────────── */
336
+ @keyframes page-in-up {
337
+ from { opacity: 0; transform: translateY(7px); filter: blur(2px); }
338
+ to { opacity: 1; transform: translateY(0); filter: blur(0); }
339
+ }
340
+ @keyframes page-in-down {
341
+ from { opacity: 0; transform: translateY(-7px); filter: blur(2px); }
342
+ to { opacity: 1; transform: translateY(0); filter: blur(0); }
343
+ }
344
+ .animate-page-in-up {
345
+ animation: page-in-up 260ms cubic-bezier(0.16,1,0.3,1) both;
346
+ }
347
+ .animate-page-in-down {
348
+ animation: page-in-down 260ms cubic-bezier(0.16,1,0.3,1) both;
349
+ }
350
+
351
+ /* ── Toast ───────────────────────────────────────────────────────── */
352
+ @keyframes toast-in {
353
+ from { opacity: 0; transform: translateY(-14px) scale(0.97); }
354
+ to { opacity: 1; transform: translateY(0) scale(1); }
355
+ }
356
+ @keyframes toast-out {
357
+ from { opacity: 1; transform: translateY(0) scale(1); }
358
+ to { opacity: 0; transform: translateY(-10px) scale(0.97); }
359
+ }
360
+ .animate-toast-in {
361
+ animation: toast-in 320ms cubic-bezier(0.34, 1.4, 0.64, 1) both;
362
+ }
363
+ .animate-toast-out {
364
+ animation: toast-out 180ms cubic-bezier(0.4, 0, 1, 1) both;
365
+ }
366
+
367
+ /* ── Popover (handled via inline transitions) ────────────────────── */
368
+
369
+ /* ── Skeleton ────────────────────────────────────────────────────── */
370
+ @keyframes skeleton-pulse {
371
+ 0%, 100% { opacity: 1; }
372
+ 50% { opacity: 0.4; }
373
+ }
374
+ .animate-skeleton-pulse {
375
+ animation: skeleton-pulse 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
376
+ }
377
+
378
+ /* A band of light crossing the empty well, fixed to the viewport so
379
+ every placeholder on screen sweeps in sync. */
380
+ @keyframes skeleton-sheen {
381
+ from { background-position: -60vw 0; }
382
+ to { background-position: 60vw 0; }
383
+ }
384
+ .skeleton-sheen::after {
385
+ content: '';
386
+ position: absolute;
387
+ inset: 0;
388
+ background-image: linear-gradient(
389
+ 90deg,
390
+ transparent 0%,
391
+ rgba(255, 255, 255, 0.75) 50%,
392
+ transparent 100%
393
+ );
394
+ background-size: 40vw 100%;
395
+ background-repeat: no-repeat;
396
+ background-attachment: fixed;
397
+ animation: skeleton-sheen 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
398
+ }
399
+ @media (prefers-reduced-motion: reduce) {
400
+ .skeleton-sheen::after { animation: none; display: none; }
401
+ }
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@blurrow/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "tactile react components: buttons you want to press, fields you want to fill in.",
5
+ "license": "MIT",
6
+ "author": "manyports (https://manyports.com)",
7
+ "homepage": "https://manyports.com",
8
+ "keywords": ["react", "components", "ui", "tailwindcss", "design-system"],
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "module": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ },
18
+ "./styles.css": "./dist/styles.css",
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": ["dist", "README.md", "LICENSE"],
22
+ "sideEffects": ["**/*.css"],
23
+ "scripts": {
24
+ "build": "tsup && cp ../../components/ui/styles.css dist/styles.css",
25
+ "prepublishOnly": "npm run build"
26
+ },
27
+ "peerDependencies": {
28
+ "react": "^19.0.0",
29
+ "react-dom": "^19.0.0",
30
+ "tailwindcss": "^4.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^19",
34
+ "@types/react-dom": "^19",
35
+ "tsup": "^8.5.0",
36
+ "typescript": "^5"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }