@proyecto-viviana/ui 0.1.0 → 0.1.2

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 (39) hide show
  1. package/dist/index.js +2 -2
  2. package/dist/index.js.map +1 -1
  3. package/package.json +6 -5
  4. package/src/alert/index.tsx +48 -0
  5. package/src/assets/favicon.png +0 -0
  6. package/src/assets/fire.gif +0 -0
  7. package/src/avatar/index.tsx +75 -0
  8. package/src/badge/index.tsx +43 -0
  9. package/src/button/Button.tsx +75 -0
  10. package/src/button/index.ts +2 -0
  11. package/src/button/types.ts +24 -0
  12. package/src/checkbox/index.tsx +258 -0
  13. package/src/components.css +975 -0
  14. package/src/custom/calendar-card/index.tsx +66 -0
  15. package/src/custom/chip/index.tsx +32 -0
  16. package/src/custom/conversation/index.tsx +105 -0
  17. package/src/custom/event-card/index.tsx +126 -0
  18. package/src/custom/lateral-nav/index.tsx +88 -0
  19. package/src/custom/logo/index.tsx +54 -0
  20. package/src/custom/nav-header/index.tsx +42 -0
  21. package/src/custom/page-layout/index.tsx +20 -0
  22. package/src/custom/profile-card/index.tsx +58 -0
  23. package/src/custom/project-card/index.tsx +59 -0
  24. package/src/custom/timeline-item/index.tsx +81 -0
  25. package/src/dialog/index.tsx +69 -0
  26. package/src/icon/icons/GitHubIcon.tsx +20 -0
  27. package/src/icon/index.tsx +48 -0
  28. package/src/index.ts +107 -0
  29. package/src/link/index.tsx +131 -0
  30. package/src/progress-bar/index.tsx +169 -0
  31. package/src/radio/index.tsx +219 -0
  32. package/src/separator/index.tsx +141 -0
  33. package/src/styles.css +450 -0
  34. package/src/switch/ToggleSwitch.tsx +113 -0
  35. package/src/switch/index.tsx +90 -0
  36. package/src/test-utils/index.ts +32 -0
  37. package/src/textfield/index.tsx +211 -0
  38. package/src/theme.css +101 -0
  39. package/src/tooltip/index.tsx +31 -0
@@ -0,0 +1,975 @@
1
+ /*
2
+ * Viviana UI Component Styles
3
+ *
4
+ * Pure CSS component styles that use theme CSS variables.
5
+ * These styles work with any theme that defines the required variables.
6
+ */
7
+
8
+ /* ===== BASE TYPOGRAPHY ===== */
9
+ /* Sen = body text, paragraphs, descriptions */
10
+ /* Jost = titles, headings, labels, buttons */
11
+
12
+ .font-sen {
13
+ font-family: 'Sen', sans-serif;
14
+ }
15
+
16
+ .font-jost {
17
+ font-family: 'Jost', sans-serif;
18
+ }
19
+
20
+ /* Base body font */
21
+ .vui-body {
22
+ font-family: 'Sen', sans-serif;
23
+ }
24
+
25
+ /* Titles and headings */
26
+ .vui-title {
27
+ font-family: 'Jost', sans-serif;
28
+ }
29
+
30
+ /* ===== CUSTOM SHADOWS ===== */
31
+ .drop-shadow-title-card {
32
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
33
+ }
34
+
35
+ .drop-shadow-logo {
36
+ filter: drop-shadow(0 0 10px rgba(223, 92, 154, 0.8));
37
+ }
38
+
39
+
40
+ /* ===== BUTTON COMPONENT ===== */
41
+ .vui-button {
42
+ font-family: 'Jost', sans-serif;
43
+ display: inline-flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ white-space: nowrap;
47
+ letter-spacing: 0.05em;
48
+ font-weight: 500;
49
+ text-transform: uppercase;
50
+ border-radius: 0.5rem;
51
+ transition: all 0.2s ease;
52
+ cursor: pointer;
53
+ border: none;
54
+ outline: none;
55
+ }
56
+
57
+ .vui-button:focus-visible {
58
+ outline: none;
59
+ box-shadow: 0 0 0 2px var(--color-bg-400), 0 0 0 4px var(--color-accent-300);
60
+ }
61
+
62
+ .vui-button:disabled {
63
+ opacity: 0.5;
64
+ cursor: not-allowed;
65
+ }
66
+
67
+ .vui-button.is-pressed {
68
+ transform: scale(0.98);
69
+ }
70
+
71
+ /* Size variants */
72
+ .vui-button--sm {
73
+ padding: 0.375rem 0.75rem;
74
+ font-size: 0.875rem;
75
+ }
76
+
77
+ .vui-button--md {
78
+ padding: 0.5rem 1rem;
79
+ font-size: 1rem;
80
+ }
81
+
82
+ .vui-button--lg {
83
+ padding: 0.75rem 1.5rem;
84
+ font-size: 1.125rem;
85
+ }
86
+
87
+ /* Full width */
88
+ .vui-button--full-width {
89
+ width: 100%;
90
+ }
91
+
92
+ /* ===== FILL VARIANTS ===== */
93
+
94
+ /* Primary = bg-primary-700, text-primary-200, border-bottom-primary-200 */
95
+ .vui-button--fill.vui-button--primary {
96
+ background: var(--color-primary-700);
97
+ color: var(--color-primary-200);
98
+ border-bottom: 1px solid var(--color-primary-200);
99
+ }
100
+
101
+ /* Secondary = bg-primary-600, text-primary-100 */
102
+ .vui-button--fill.vui-button--secondary {
103
+ background: var(--color-primary-600);
104
+ color: var(--color-primary-100);
105
+ }
106
+
107
+ /* Accent = bg-accent, text-white */
108
+ .vui-button--fill.vui-button--accent {
109
+ background: var(--color-accent);
110
+ color: white;
111
+ }
112
+
113
+ /* Positive = bg-success-600, text-success-100, border-success-400 */
114
+ .vui-button--fill.vui-button--positive {
115
+ background: var(--color-success-600);
116
+ color: var(--color-success-100);
117
+ border: 1px solid var(--color-success-400);
118
+ }
119
+
120
+ /* Negative = bg-danger-600, text-danger-100, border-danger-400 */
121
+ .vui-button--fill.vui-button--negative {
122
+ background: var(--color-danger-600);
123
+ color: var(--color-danger-100);
124
+ border: 1px solid var(--color-danger-400);
125
+ }
126
+
127
+ /* Ghost = transparent, text-primary-300, hover:bg-bg-200 */
128
+ .vui-button--fill.vui-button--ghost,
129
+ .vui-button--outline.vui-button--ghost {
130
+ background: transparent;
131
+ color: var(--color-primary-300);
132
+ }
133
+ .vui-button--fill.vui-button--ghost:hover:not(:disabled),
134
+ .vui-button--outline.vui-button--ghost:hover:not(:disabled) {
135
+ background: var(--color-bg-200);
136
+ }
137
+
138
+ /* Link = transparent, text-accent-200, hover:text-accent-300 */
139
+ .vui-button--fill.vui-button--link,
140
+ .vui-button--outline.vui-button--link {
141
+ background: transparent;
142
+ color: var(--color-accent-200);
143
+ }
144
+ .vui-button--fill.vui-button--link:hover:not(:disabled),
145
+ .vui-button--outline.vui-button--link:hover:not(:disabled) {
146
+ color: var(--color-accent-300);
147
+ }
148
+
149
+ /* ===== OUTLINE VARIANTS ===== */
150
+
151
+ /* Primary outline = bg-bg-400, text-primary-500, border-primary-500 */
152
+ .vui-button--outline.vui-button--primary {
153
+ background: var(--color-bg-400);
154
+ color: var(--color-primary-500);
155
+ border: 1px solid var(--color-primary-500);
156
+ }
157
+
158
+ /* Secondary outline = transparent, text-primary-300, border-primary-600 */
159
+ .vui-button--outline.vui-button--secondary {
160
+ background: transparent;
161
+ color: var(--color-primary-300);
162
+ border: 1px solid var(--color-primary-600);
163
+ }
164
+
165
+ /* Accent outline = transparent, text-accent-200, border-accent */
166
+ .vui-button--outline.vui-button--accent {
167
+ background: transparent;
168
+ color: var(--color-accent-200);
169
+ border: 1px solid var(--color-accent);
170
+ }
171
+
172
+ /* Positive outline = transparent, text-success-400, border-success-400 */
173
+ .vui-button--outline.vui-button--positive {
174
+ background: transparent;
175
+ color: var(--color-success-400);
176
+ border: 1px solid var(--color-success-400);
177
+ }
178
+
179
+ /* Negative outline = transparent, text-danger-400, border-danger-400 */
180
+ .vui-button--outline.vui-button--negative {
181
+ background: transparent;
182
+ color: var(--color-danger-400);
183
+ border: 1px solid var(--color-danger-400);
184
+ }
185
+
186
+ /* ===== ICON COMPONENT ===== */
187
+ .vui-icon {
188
+ position: relative;
189
+ display: inline-flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ }
193
+
194
+ .vui-icon__main {
195
+ position: relative;
196
+ z-index: 1;
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: center;
200
+ }
201
+
202
+ .vui-icon__shadow {
203
+ position: absolute;
204
+ top: 2px;
205
+ left: 0;
206
+ z-index: 0;
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ opacity: 0.8;
211
+ }
212
+
213
+ /* ===== CHIP COMPONENT ===== */
214
+ .vui-chip {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ padding: 0.125rem 0.5rem;
219
+ font-size: 0.75rem;
220
+ font-weight: 600;
221
+ border-radius: 9999px;
222
+ text-transform: uppercase;
223
+ }
224
+
225
+ .vui-chip--primary {
226
+ background: var(--color-primary-700);
227
+ color: var(--color-primary-100);
228
+ border-bottom: 1px solid var(--color-primary-200);
229
+ }
230
+
231
+ .vui-chip--accent {
232
+ background: var(--color-accent);
233
+ color: white;
234
+ }
235
+
236
+ .vui-chip--success {
237
+ background: var(--color-success-600);
238
+ color: var(--color-success-100);
239
+ }
240
+
241
+ .vui-chip--warning {
242
+ background: var(--color-warning-600);
243
+ color: var(--color-warning-100);
244
+ }
245
+
246
+ .vui-chip--danger {
247
+ background: var(--color-danger-600);
248
+ color: var(--color-danger-100);
249
+ }
250
+
251
+ /* ===== BADGE COMPONENT ===== */
252
+ .vui-badge {
253
+ display: inline-flex;
254
+ align-items: center;
255
+ justify-content: center;
256
+ padding: 0.25rem 0.75rem;
257
+ font-size: 0.875rem;
258
+ font-weight: 500;
259
+ border-radius: 0.375rem;
260
+ }
261
+
262
+ .vui-badge--primary {
263
+ background: var(--color-primary-700);
264
+ color: var(--color-primary-100);
265
+ }
266
+
267
+ .vui-badge--accent {
268
+ background: var(--color-accent);
269
+ color: white;
270
+ }
271
+
272
+ .vui-badge--success {
273
+ background: var(--color-success-600);
274
+ color: var(--color-success-100);
275
+ }
276
+
277
+ .vui-badge--warning {
278
+ background: var(--color-warning-600);
279
+ color: var(--color-warning-100);
280
+ }
281
+
282
+ .vui-badge--danger {
283
+ background: var(--color-danger-600);
284
+ color: var(--color-danger-100);
285
+ }
286
+
287
+ /* ===== ALERT COMPONENT ===== */
288
+ .vui-alert {
289
+ display: flex;
290
+ align-items: flex-start;
291
+ gap: 0.75rem;
292
+ padding: 1rem;
293
+ border-radius: 0.5rem;
294
+ border-width: 1px;
295
+ }
296
+
297
+ .vui-alert--info {
298
+ background: color-mix(in srgb, var(--color-primary-700) 20%, transparent);
299
+ border-color: var(--color-primary-600);
300
+ color: var(--color-primary-200);
301
+ }
302
+
303
+ .vui-alert--success {
304
+ background: color-mix(in srgb, var(--color-success-600) 20%, transparent);
305
+ border-color: var(--color-success-600);
306
+ color: var(--color-success-100);
307
+ }
308
+
309
+ .vui-alert--warning {
310
+ background: color-mix(in srgb, var(--color-warning-600) 20%, transparent);
311
+ border-color: var(--color-warning-600);
312
+ color: var(--color-warning-100);
313
+ }
314
+
315
+ .vui-alert--error {
316
+ background: color-mix(in srgb, var(--color-danger-600) 20%, transparent);
317
+ border-color: var(--color-danger-400);
318
+ color: var(--color-danger-100);
319
+ }
320
+
321
+ /* ===== AVATAR COMPONENT ===== */
322
+ .vui-avatar {
323
+ display: inline-flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ border-radius: 9999px;
327
+ overflow: hidden;
328
+ background: var(--color-bg-300);
329
+ color: var(--color-primary-300);
330
+ font-weight: 600;
331
+ }
332
+
333
+ .vui-avatar--sm {
334
+ width: 2rem;
335
+ height: 2rem;
336
+ font-size: 0.75rem;
337
+ }
338
+
339
+ .vui-avatar--md {
340
+ width: 2.5rem;
341
+ height: 2.5rem;
342
+ font-size: 0.875rem;
343
+ }
344
+
345
+ .vui-avatar--lg {
346
+ width: 3rem;
347
+ height: 3rem;
348
+ font-size: 1rem;
349
+ }
350
+
351
+ .vui-avatar--xl {
352
+ width: 4rem;
353
+ height: 4rem;
354
+ font-size: 1.25rem;
355
+ }
356
+
357
+ /* ===== CARD COMPONENT ===== */
358
+ .vui-card {
359
+ background: var(--color-bg-300);
360
+ border: 1px solid var(--color-primary-600);
361
+ border-radius: 0.75rem;
362
+ overflow: hidden;
363
+ }
364
+
365
+ .vui-card--accent-border {
366
+ border-bottom-color: var(--color-accent-500);
367
+ }
368
+
369
+ /* ===== GRADIENTS ===== */
370
+ .hero-gradient {
371
+ background: linear-gradient(135deg, var(--color-bg-300) 0%, var(--color-bg-400) 100%);
372
+ }
373
+
374
+ .gradient-text {
375
+ background: linear-gradient(135deg, var(--color-primary-300), var(--color-accent-300));
376
+ -webkit-background-clip: text;
377
+ -webkit-text-fill-color: transparent;
378
+ background-clip: text;
379
+ }
380
+
381
+ /* ===== PROSE/DOCS ===== */
382
+ .prose {
383
+ max-width: 65ch;
384
+ }
385
+
386
+ .prose h1 {
387
+ font-family: 'Jost', sans-serif;
388
+ font-size: 2.25rem;
389
+ font-weight: 700;
390
+ margin-bottom: 1rem;
391
+ color: var(--color-primary-100);
392
+ }
393
+
394
+ .prose h2 {
395
+ font-family: 'Jost', sans-serif;
396
+ font-size: 1.5rem;
397
+ font-weight: 600;
398
+ margin-top: 2rem;
399
+ margin-bottom: 0.75rem;
400
+ color: var(--color-primary-200);
401
+ }
402
+
403
+ .prose h3 {
404
+ font-family: 'Jost', sans-serif;
405
+ font-size: 1.25rem;
406
+ font-weight: 600;
407
+ margin-top: 1.5rem;
408
+ margin-bottom: 0.5rem;
409
+ color: var(--color-primary-200);
410
+ }
411
+
412
+ .prose p {
413
+ margin-bottom: 1rem;
414
+ line-height: 1.75;
415
+ color: var(--color-primary-300);
416
+ }
417
+
418
+ .prose code {
419
+ background: var(--color-bg-300);
420
+ padding: 0.125rem 0.375rem;
421
+ border-radius: 0.25rem;
422
+ font-family: var(--font-mono);
423
+ font-size: 0.875em;
424
+ color: var(--color-accent-200);
425
+ }
426
+
427
+ .prose pre {
428
+ background: var(--color-bg-400);
429
+ color: var(--color-primary-100);
430
+ padding: 1rem;
431
+ border-radius: 0.5rem;
432
+ overflow-x: auto;
433
+ margin: 1rem 0;
434
+ }
435
+
436
+ .prose pre code {
437
+ background: transparent;
438
+ padding: 0;
439
+ color: inherit;
440
+ }
441
+
442
+ /* ===== SIDEBAR ===== */
443
+ .sidebar-link {
444
+ display: block;
445
+ padding: 0.5rem 1rem;
446
+ border-radius: 0.375rem;
447
+ color: var(--color-primary-300);
448
+ transition: all 0.15s;
449
+ }
450
+
451
+ .sidebar-link:hover {
452
+ background: var(--color-bg-300);
453
+ color: var(--color-primary-100);
454
+ }
455
+
456
+ .sidebar-link.active {
457
+ background: var(--color-primary-700);
458
+ color: var(--color-primary-100);
459
+ font-weight: 500;
460
+ }
461
+
462
+ /* ===== LOGO COMPONENT ===== */
463
+ .vui-logo {
464
+ display: inline-flex;
465
+ align-items: baseline;
466
+ font-family: 'Jost', sans-serif;
467
+ text-transform: uppercase;
468
+ letter-spacing: 0.01em;
469
+ }
470
+
471
+ .vui-logo__first {
472
+ color: var(--color-primary-800);
473
+ font-weight: 300;
474
+ }
475
+
476
+ .vui-logo__second {
477
+ position: relative;
478
+ color: var(--color-primary-500);
479
+ font-weight: 900;
480
+ -webkit-text-stroke: 2px rgba(255, 255, 255, 0.9);
481
+ paint-order: stroke fill;
482
+ }
483
+
484
+ .vui-logo__second::before {
485
+ content: attr(data-text);
486
+ position: absolute;
487
+ left: 0;
488
+ top: 0;
489
+ z-index: -1;
490
+ color: transparent;
491
+ -webkit-text-stroke: 0;
492
+ text-shadow: 4px 3px 0 var(--color-accent);
493
+ }
494
+
495
+ /* Logo size variants */
496
+ .vui-logo--sm {
497
+ font-size: 2.5rem;
498
+ }
499
+
500
+ .vui-logo--md {
501
+ font-size: 3.5rem;
502
+ }
503
+
504
+ .vui-logo--lg {
505
+ font-size: 2.0rem;
506
+ }
507
+
508
+ .vui-logo--lg .vui-logo__second::before {
509
+ text-shadow: 5px 4px 0 var(--color-accent);
510
+ }
511
+
512
+ .vui-logo--xl {
513
+ font-size: 6rem;
514
+ }
515
+
516
+ .vui-logo--xl .vui-logo__second::before {
517
+ text-shadow: 6px 5px 0 var(--color-accent);
518
+ }
519
+
520
+ /* ===== HEADER COMPONENT ===== */
521
+ .vui-header {
522
+ position: fixed;
523
+ top: 0;
524
+ left: 0;
525
+ right: 0;
526
+ z-index: 50;
527
+ border-bottom: 3px solid var(--color-accent);
528
+ background: color-mix(in srgb, var(--color-bg-400) 80%, transparent);
529
+ backdrop-filter: blur(8px);
530
+ -webkit-backdrop-filter: blur(8px);
531
+ }
532
+
533
+ .vui-header__container {
534
+ margin-left: auto;
535
+ margin-right: auto;
536
+ max-width: 72rem;
537
+ height: 70px;
538
+ display: flex;
539
+ align-items: center;
540
+ justify-content: space-between;
541
+ }
542
+
543
+ .vui-header__nav {
544
+ display: flex;
545
+ align-items: center;
546
+ gap: 1.5rem;
547
+ }
548
+
549
+ .vui-header__link {
550
+ font-family: 'Jost', sans-serif;
551
+ font-size: 0.875rem;
552
+ font-weight: 500;
553
+ color: var(--color-primary-300);
554
+ transition: color 0.15s;
555
+ }
556
+
557
+ .vui-header__link:hover {
558
+ color: var(--color-primary-100);
559
+ }
560
+
561
+ .vui-header__link--active {
562
+ color: var(--color-accent);
563
+ }
564
+
565
+ .vui-header__link--active:hover {
566
+ color: var(--color-accent-300);
567
+ }
568
+
569
+ /* ===== PAGE LAYOUT ===== */
570
+ .vui-page {
571
+ display: flex;
572
+ flex-direction: column;
573
+ min-height: 100vh;
574
+ background: var(--color-bg-100);
575
+ font-family: 'Sen', sans-serif;
576
+ }
577
+
578
+ .vui-page h1,
579
+ .vui-page h2,
580
+ .vui-page h3,
581
+ .vui-page h4,
582
+ .vui-page h5,
583
+ .vui-page h6 {
584
+ font-family: 'Jost', sans-serif;
585
+ }
586
+
587
+ /* ===== LANDING PAGE LAYOUT ===== */
588
+ .vui-landing {
589
+ display: flex;
590
+ flex-direction: column;
591
+ min-height: 100vh;
592
+ background: var(--color-bg-100);
593
+ font-family: 'Sen', sans-serif;
594
+ }
595
+
596
+ /* Hero Section */
597
+ .vui-hero {
598
+ min-height: 50vh;
599
+ padding-top: 7.5rem;
600
+ padding-bottom: 2rem;
601
+ background: var(--color-bg-200);
602
+ border-bottom: 1px solid var(--color-primary-600);
603
+ display: flex;
604
+ align-items: center;
605
+ justify-content: center;
606
+ }
607
+
608
+ .vui-hero__container {
609
+ margin-left: auto;
610
+ margin-right: auto;
611
+ max-width: 56rem;
612
+ padding-left: 1.5rem;
613
+ padding-right: 1.5rem;
614
+ text-align: center;
615
+ width: 100%;
616
+ }
617
+
618
+ .vui-hero__title {
619
+ font-family: 'Jost', sans-serif;
620
+ font-size: 3rem;
621
+ font-weight: 800;
622
+ letter-spacing: -0.025em;
623
+ color: var(--color-primary-100);
624
+ line-height: 1.1;
625
+ }
626
+
627
+ @media (min-width: 640px) {
628
+ .vui-hero__title {
629
+ font-size: 3.75rem;
630
+ }
631
+ }
632
+
633
+ @media (min-width: 1024px) {
634
+ .vui-hero__title {
635
+ font-size: 4.5rem;
636
+ }
637
+ }
638
+
639
+ .vui-hero__subtitle {
640
+ margin-top: 1.5rem;
641
+ margin-left: auto;
642
+ margin-right: auto;
643
+ max-width: 42rem;
644
+ font-size: 1.25rem;
645
+ color: var(--color-primary-300);
646
+ line-height: 1.75;
647
+ }
648
+
649
+ .vui-hero__actions {
650
+ margin-top: 2.5rem;
651
+ display: flex;
652
+ justify-content: center;
653
+ gap: 1rem;
654
+ }
655
+
656
+ /* Section */
657
+ .vui-section {
658
+ padding-top: 2rem;
659
+ padding-bottom: 2rem;
660
+ }
661
+
662
+ .vui-section--alt {
663
+ background: var(--color-bg-200);
664
+ }
665
+
666
+ .vui-section__container {
667
+ margin-left: auto;
668
+ margin-right: auto;
669
+ max-width: 72rem;
670
+ padding-left: 1.5rem;
671
+ padding-right: 1.5rem;
672
+ }
673
+
674
+ .vui-section__container--narrow {
675
+ max-width: 56rem;
676
+ }
677
+
678
+ .vui-section__header {
679
+ text-align: center;
680
+ margin-bottom: 3rem;
681
+ }
682
+
683
+ .vui-section__title {
684
+ font-family: 'Jost', sans-serif;
685
+ font-size: 1.875rem;
686
+ font-weight: 700;
687
+ color: var(--color-primary-100);
688
+ }
689
+
690
+ .vui-section__description {
691
+ margin-top: 1rem;
692
+ margin-left: auto;
693
+ margin-right: auto;
694
+ max-width: 42rem;
695
+ font-size: 1.125rem;
696
+ color: var(--color-primary-300);
697
+ }
698
+
699
+ /* Feature Grid */
700
+ .vui-feature-grid {
701
+ display: grid;
702
+ gap: 2rem;
703
+ }
704
+
705
+ @media (min-width: 640px) {
706
+ .vui-feature-grid {
707
+ grid-template-columns: repeat(2, 1fr);
708
+ }
709
+ }
710
+
711
+ @media (min-width: 1024px) {
712
+ .vui-feature-grid {
713
+ grid-template-columns: repeat(3, 1fr);
714
+ }
715
+ }
716
+
717
+ /* Feature Card */
718
+ .vui-feature-card {
719
+ padding: 1.5rem;
720
+ border-radius: 0.75rem;
721
+ border: 1px solid var(--color-bg-300);
722
+ background: var(--color-bg-200);
723
+ transition: box-shadow 0.2s, border-color 0.2s;
724
+ }
725
+
726
+ .vui-feature-card--alt {
727
+ background: var(--color-bg-300);
728
+ border-color: var(--color-bg-400);
729
+ }
730
+
731
+ .vui-feature-card:hover {
732
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
733
+ border-color: var(--color-primary-600);
734
+ }
735
+
736
+ .vui-feature-card__icon {
737
+ font-size: 1.875rem;
738
+ margin-bottom: 1rem;
739
+ }
740
+
741
+ .vui-feature-card__title {
742
+ font-family: 'Jost', sans-serif;
743
+ font-size: 1.125rem;
744
+ font-weight: 600;
745
+ color: var(--color-primary-100);
746
+ }
747
+
748
+ .vui-feature-card__description {
749
+ margin-top: 0.5rem;
750
+ color: var(--color-primary-300);
751
+ line-height: 1.625;
752
+ }
753
+
754
+ /* Code Block */
755
+ .vui-code-block {
756
+ overflow: hidden;
757
+ border-radius: 0.75rem;
758
+ border: 1px solid var(--color-bg-300);
759
+ background: var(--color-bg-400);
760
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
761
+ }
762
+
763
+ .vui-code-block__header {
764
+ display: flex;
765
+ align-items: center;
766
+ gap: 0.5rem;
767
+ padding: 0.75rem 1rem;
768
+ border-bottom: 1px solid var(--color-bg-300);
769
+ background: var(--color-bg-300);
770
+ }
771
+
772
+ .vui-code-block__dot {
773
+ width: 0.75rem;
774
+ height: 0.75rem;
775
+ border-radius: 9999px;
776
+ }
777
+
778
+ .vui-code-block__dot--red {
779
+ background: var(--color-danger-400);
780
+ }
781
+
782
+ .vui-code-block__dot--yellow {
783
+ background: var(--color-warning-400);
784
+ }
785
+
786
+ .vui-code-block__dot--green {
787
+ background: var(--color-success-400);
788
+ }
789
+
790
+ .vui-code-block__filename {
791
+ margin-left: 1rem;
792
+ font-size: 0.875rem;
793
+ color: var(--color-primary-400);
794
+ }
795
+
796
+ .vui-code-block__content {
797
+ padding: 1.5rem;
798
+ overflow-x: auto;
799
+ }
800
+
801
+ .vui-code-block__code {
802
+ font-size: 0.875rem;
803
+ line-height: 1.625;
804
+ color: var(--color-primary-200);
805
+ font-family: var(--font-mono);
806
+ }
807
+
808
+ /* Footer */
809
+ .vui-footer {
810
+ border-top: 1px solid var(--color-bg-300);
811
+ background: var(--color-bg-300);
812
+ }
813
+
814
+ .vui-footer__container {
815
+ margin-left: auto;
816
+ margin-right: auto;
817
+ max-width: 72rem;
818
+ padding: 2rem 1.5rem;
819
+ display: flex;
820
+ flex-direction: column;
821
+ align-items: center;
822
+ justify-content: space-between;
823
+ gap: 1.5rem;
824
+ }
825
+
826
+ @media (min-width: 640px) {
827
+ .vui-footer__container {
828
+ flex-direction: row;
829
+ }
830
+ }
831
+
832
+ .vui-footer__text {
833
+ font-size: 0.875rem;
834
+ color: var(--color-primary-400);
835
+ }
836
+
837
+ .vui-footer__links {
838
+ display: flex;
839
+ gap: 1.5rem;
840
+ }
841
+
842
+ .vui-footer__link {
843
+ font-family: 'Jost', sans-serif;
844
+ font-size: 0.875rem;
845
+ color: var(--color-primary-300);
846
+ transition: color 0.15s;
847
+ }
848
+
849
+ .vui-footer__link:hover {
850
+ color: var(--color-primary-100);
851
+ }
852
+
853
+ /* Gradient Text Utility */
854
+ .vui-gradient-text {
855
+ background: linear-gradient(135deg, var(--color-primary-300), var(--color-accent-300));
856
+ -webkit-background-clip: text;
857
+ -webkit-text-fill-color: transparent;
858
+ background-clip: text;
859
+ }
860
+
861
+ /* ===== TOOLTIP COMPONENT ===== */
862
+ .vui-tooltip {
863
+ position: relative;
864
+ display: inline-flex;
865
+ }
866
+
867
+ .vui-tooltip__trigger {
868
+ display: inline-flex;
869
+ }
870
+
871
+ .vui-tooltip__content {
872
+ position: absolute;
873
+ z-index: 10;
874
+ padding: 0.5rem 1rem;
875
+ background: var(--color-primary-700);
876
+ color: var(--color-primary-200);
877
+ border: 1px solid var(--color-primary-500);
878
+ border-radius: 0.5rem;
879
+ font-family: 'Jost', sans-serif;
880
+ font-size: 0.875rem;
881
+ font-weight: 500;
882
+ white-space: nowrap;
883
+ opacity: 0;
884
+ pointer-events: none;
885
+ transition: opacity 0.15s ease-in-out, transform 0.15s ease-in-out;
886
+ }
887
+
888
+ .vui-tooltip__content--bottom {
889
+ top: calc(100% + 0.5rem);
890
+ left: 50%;
891
+ transform: translateX(-50%) translateY(0.25rem);
892
+ }
893
+
894
+ .vui-tooltip__content--top {
895
+ bottom: calc(100% + 0.5rem);
896
+ left: 50%;
897
+ transform: translateX(-50%) translateY(-0.25rem);
898
+ }
899
+
900
+ .vui-tooltip:hover .vui-tooltip__content {
901
+ opacity: 1;
902
+ transform: translateX(-50%) translateY(0);
903
+ }
904
+
905
+ /* ===== PROJECT CARD COMPONENT ===== */
906
+ .vui-project-card {
907
+ position: relative;
908
+ display: grid;
909
+ place-items: center;
910
+ padding: 1rem;
911
+ border-radius: 0.75rem;
912
+ border: 1px solid var(--color-primary-700);
913
+ background: var(--color-bg-200);
914
+ transition: background 0.15s ease-in-out;
915
+ text-decoration: none;
916
+ }
917
+
918
+ .vui-project-card:hover {
919
+ background: var(--color-bg-300);
920
+ }
921
+
922
+ .vui-project-card--sm {
923
+ height: 4rem;
924
+ }
925
+
926
+ .vui-project-card--md {
927
+ height: 6rem;
928
+ }
929
+
930
+ .vui-project-card--lg {
931
+ padding: 1rem;
932
+ }
933
+
934
+ .vui-project-card--inactive {
935
+ filter: grayscale(1);
936
+ background: var(--color-bg-400);
937
+ }
938
+
939
+ .vui-project-card--inactive:hover {
940
+ background: var(--color-bg-400);
941
+ }
942
+
943
+ .vui-project-card__tooltip {
944
+ position: absolute;
945
+ top: calc(100% + 0.5rem);
946
+ z-index: 10;
947
+ padding: 0.5rem 1rem;
948
+ background: var(--color-primary-700);
949
+ color: var(--color-primary-200);
950
+ border: 1px solid var(--color-primary-500);
951
+ border-radius: 0.5rem;
952
+ font-family: 'Jost', sans-serif;
953
+ font-size: 0.875rem;
954
+ font-weight: 500;
955
+ white-space: nowrap;
956
+ opacity: 0;
957
+ pointer-events: none;
958
+ transition: opacity 0.15s ease-in-out;
959
+ }
960
+
961
+ .vui-project-card:hover .vui-project-card__tooltip {
962
+ opacity: 1;
963
+ }
964
+
965
+ .vui-project-card__image {
966
+ max-height: 2rem;
967
+ max-width: 100%;
968
+ object-fit: contain;
969
+ }
970
+
971
+ .vui-project-card--lg .vui-project-card__image {
972
+ max-height: none;
973
+ max-width: 300px;
974
+ width: 100%;
975
+ }