@fluid-theme/core 0.4.3

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 (48) hide show
  1. package/AGENTS.md +32 -0
  2. package/CHANGELOG.md +159 -0
  3. package/CLAUDE.md +104 -0
  4. package/GEMINI.md +48 -0
  5. package/LICENSE +21 -0
  6. package/README.md +253 -0
  7. package/dist/fluid.min.css +2 -0
  8. package/fluid-agent-kit/README.md +57 -0
  9. package/fluid-agent-kit/skills/accessibility.md +41 -0
  10. package/fluid-agent-kit/skills/css-conventions.md +51 -0
  11. package/fluid-agent-kit/skills/image-optimization.md +115 -0
  12. package/fluid-agent-kit/skills/ux-rules.md +43 -0
  13. package/package.json +68 -0
  14. package/src/animations/scroll-reveal.css +224 -0
  15. package/src/components/accordion.css +250 -0
  16. package/src/components/alert.css +453 -0
  17. package/src/components/avatar.css +192 -0
  18. package/src/components/badge.css +182 -0
  19. package/src/components/button.css +387 -0
  20. package/src/components/card.css +650 -0
  21. package/src/components/chip.css +143 -0
  22. package/src/components/dropdown.css +335 -0
  23. package/src/components/empty-state.css +105 -0
  24. package/src/components/form.css +508 -0
  25. package/src/components/hero.css +293 -0
  26. package/src/components/indicator.css +455 -0
  27. package/src/components/loading.css +274 -0
  28. package/src/components/modal.css +364 -0
  29. package/src/components/nav.css +726 -0
  30. package/src/components/scroll-progress.css +104 -0
  31. package/src/components/search-input.css +125 -0
  32. package/src/components/settings-panel.css +603 -0
  33. package/src/components/step-indicator.css +188 -0
  34. package/src/components/table.css +350 -0
  35. package/src/components/themed-images.css +229 -0
  36. package/src/components/tooltip.css +247 -0
  37. package/src/components/version-badge.css +70 -0
  38. package/src/core/base.css +884 -0
  39. package/src/core/reset.css +159 -0
  40. package/src/core/tokens.css +2416 -0
  41. package/src/fluid.css +242 -0
  42. package/src/layouts/positioning.css +626 -0
  43. package/src/sections/cta.css +210 -0
  44. package/src/sections/features.css +356 -0
  45. package/src/sections/footer.css +283 -0
  46. package/src/sections/stats.css +234 -0
  47. package/src/sections/team.css +181 -0
  48. package/src/sections/testimonials.css +251 -0
@@ -0,0 +1,603 @@
1
+ /**
2
+ * Fluid Framework - Settings Drawer Component
3
+ * @layer components
4
+ *
5
+ * A slide-out drawer for theme customization.
6
+ * Slides in from the right edge with a backdrop.
7
+ *
8
+ * Structure:
9
+ * .settings-drawer (container, covers viewport when open)
10
+ * .settings-drawer__backdrop (clickable overlay)
11
+ * .settings-drawer__panel (actual drawer)
12
+ * .settings-fab (floating action button)
13
+ */
14
+
15
+ @layer components {
16
+ /* ========================================
17
+ FLOATING ACTION BUTTON (FAB)
18
+ Always visible in bottom-right corner
19
+ ======================================== */
20
+
21
+ .settings-fab {
22
+ /* Reset */
23
+ appearance: none;
24
+ border: none;
25
+ background: none;
26
+ cursor: pointer;
27
+
28
+ /* Position */
29
+ position: fixed;
30
+ inset-block-end: var(--space-5);
31
+ inset-inline-end: var(--space-5);
32
+ z-index: var(--z-overlay);
33
+
34
+ /* Sizing */
35
+ inline-size: 3.5rem;
36
+ block-size: 3.5rem;
37
+ padding: 0;
38
+
39
+ /* Visual */
40
+ background-color: var(--accent);
41
+ color: var(--white);
42
+ border-radius: var(--radius-full);
43
+ box-shadow: var(--shadow-lg);
44
+
45
+ /* Layout */
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+
50
+ /* Transitions */
51
+ transition:
52
+ background-color var(--duration-normal) var(--ease-fluid),
53
+ transform var(--duration-normal) var(--ease-settle),
54
+ box-shadow var(--duration-normal) var(--ease-fluid);
55
+ }
56
+
57
+ .settings-fab:hover {
58
+ background-color: var(--accent-hover);
59
+ transform: scale(1.08);
60
+ box-shadow: var(--shadow-xl);
61
+ }
62
+
63
+ .settings-fab:active {
64
+ transform: scale(0.95);
65
+ }
66
+
67
+ .settings-fab:focus-visible {
68
+ outline: 2px solid transparent;
69
+ box-shadow:
70
+ var(--shadow-lg),
71
+ 0 0 0 3px var(--color-background),
72
+ 0 0 0 5px var(--accent);
73
+ }
74
+
75
+ /* Rotate when open */
76
+ .settings-fab[aria-expanded="true"] {
77
+ transform: rotate(60deg);
78
+ }
79
+
80
+ .settings-fab[aria-expanded="true"]:hover {
81
+ transform: rotate(60deg) scale(1.08);
82
+ }
83
+
84
+
85
+ /* ========================================
86
+ DRAWER CONTAINER
87
+ Full viewport overlay when open
88
+ ======================================== */
89
+
90
+ .settings-drawer {
91
+ position: fixed;
92
+ inset: 0;
93
+ z-index: calc(var(--z-overlay) + 1);
94
+
95
+ /* Hidden by default - not interactive */
96
+ pointer-events: none;
97
+ visibility: hidden;
98
+ }
99
+
100
+ .settings-drawer[data-open] {
101
+ pointer-events: auto;
102
+ visibility: visible;
103
+ }
104
+
105
+
106
+ /* ========================================
107
+ BACKDROP
108
+ Semi-transparent overlay behind drawer
109
+ ======================================== */
110
+
111
+ .settings-drawer__backdrop {
112
+ position: absolute;
113
+ inset: 0;
114
+ background-color: oklch(from var(--theme-dark) l c h / 0.4);
115
+ opacity: 0;
116
+ transition: opacity var(--duration-normal) var(--ease-fluid);
117
+ }
118
+
119
+ [data-theme="dark"] .settings-drawer__backdrop {
120
+ background-color: oklch(0% 0 0 / 0.6);
121
+ }
122
+
123
+ .settings-drawer[data-open] .settings-drawer__backdrop {
124
+ opacity: 1;
125
+ }
126
+
127
+
128
+ /* ========================================
129
+ DRAWER PANEL
130
+ Slides in from right edge
131
+ ======================================== */
132
+
133
+ .settings-drawer__panel {
134
+ --_drawer-width: 22rem;
135
+
136
+ position: absolute;
137
+ inset-block: 0;
138
+ inset-inline-end: 0;
139
+ inline-size: min(var(--_drawer-width), 90vw);
140
+
141
+ /* Visual */
142
+ background-color: var(--color-surface-raised);
143
+ border-inline-start: 1px solid var(--color-border-subtle);
144
+ box-shadow: var(--shadow-xl);
145
+
146
+ /* Layout */
147
+ display: flex;
148
+ flex-direction: column;
149
+ overflow: hidden;
150
+
151
+ /* Animation */
152
+ transform: translateX(100%);
153
+ transition: transform var(--duration-slow) var(--ease-settle);
154
+ }
155
+
156
+ .settings-drawer[data-open] .settings-drawer__panel {
157
+ transform: translateX(0);
158
+ }
159
+
160
+
161
+ /* ========================================
162
+ DRAWER HEADER
163
+ ======================================== */
164
+
165
+ .settings-drawer__header {
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: space-between;
169
+ padding: var(--space-4) var(--space-5);
170
+ border-block-end: 1px solid var(--color-border-subtle);
171
+ flex-shrink: 0;
172
+ }
173
+
174
+ .settings-drawer__title {
175
+ font-size: var(--font-size-lg);
176
+ font-weight: var(--weight-semibold);
177
+ margin: 0;
178
+ color: var(--color-text);
179
+ }
180
+
181
+ .settings-drawer__close {
182
+ appearance: none;
183
+ border: none;
184
+ background: none;
185
+ padding: var(--space-2);
186
+ margin: calc(var(--space-2) * -1);
187
+ cursor: pointer;
188
+ color: var(--color-text-muted);
189
+ border-radius: var(--radius-md);
190
+ transition: all var(--duration-fast) var(--ease-fluid);
191
+ }
192
+
193
+ .settings-drawer__close:hover {
194
+ background-color: var(--color-surface);
195
+ color: var(--color-text);
196
+ }
197
+
198
+
199
+ /* ========================================
200
+ DRAWER BODY
201
+ Scrollable content area
202
+ ======================================== */
203
+
204
+ .settings-drawer__body {
205
+ flex: 1;
206
+ overflow-y: auto;
207
+ padding: var(--space-5);
208
+ display: flex;
209
+ flex-direction: column;
210
+ gap: var(--space-5);
211
+ }
212
+
213
+
214
+ /* ========================================
215
+ DRAWER FOOTER
216
+ ======================================== */
217
+
218
+ .settings-drawer__footer {
219
+ padding: var(--space-4) var(--space-5);
220
+ border-block-start: 1px solid var(--color-border-subtle);
221
+ flex-shrink: 0;
222
+ }
223
+
224
+ .settings-drawer__footer .btn {
225
+ inline-size: 100%;
226
+ justify-content: center;
227
+ gap: var(--space-2);
228
+ }
229
+
230
+
231
+ /* ========================================
232
+ SETTINGS DIVIDER
233
+ ======================================== */
234
+
235
+ .settings-divider {
236
+ border: none;
237
+ border-block-start: 1px solid var(--color-border-subtle);
238
+ margin: 0;
239
+ }
240
+
241
+
242
+ /* ========================================
243
+ SETTINGS SECTION
244
+ ======================================== */
245
+
246
+ .settings-section {
247
+ display: flex;
248
+ flex-direction: column;
249
+ gap: var(--space-3);
250
+ }
251
+
252
+ .settings-section__label {
253
+ font-size: var(--font-size-xs);
254
+ font-weight: var(--weight-semibold);
255
+ text-transform: uppercase;
256
+ letter-spacing: var(--tracking-wider);
257
+ color: var(--color-text-subtle);
258
+ margin: 0;
259
+ }
260
+
261
+ .settings-section__hint {
262
+ font-size: var(--font-size-xs);
263
+ color: var(--color-text-muted);
264
+ margin: calc(var(--space-2) * -1) 0 0 0;
265
+ }
266
+
267
+
268
+ /* ========================================
269
+ THEME GRID
270
+ Visual theme selection cards
271
+ ======================================== */
272
+
273
+ .theme-grid {
274
+ display: grid;
275
+ grid-template-columns: repeat(2, 1fr);
276
+ gap: var(--space-2);
277
+ }
278
+
279
+ .theme-card {
280
+ /* Reset */
281
+ appearance: none;
282
+ border: none;
283
+ background: none;
284
+ cursor: pointer;
285
+ text-align: center;
286
+
287
+ /* Visual */
288
+ background-color: var(--color-surface);
289
+ border: 2px solid var(--color-border);
290
+ border-radius: var(--radius-lg);
291
+ padding: var(--space-3);
292
+
293
+ /* Layout */
294
+ display: flex;
295
+ flex-direction: column;
296
+ align-items: center;
297
+ gap: var(--space-1);
298
+
299
+ /* Transition */
300
+ transition: all var(--duration-fast) var(--ease-fluid);
301
+ }
302
+
303
+ .theme-card:hover {
304
+ background-color: var(--color-surface-raised);
305
+ border-color: var(--color-text-muted);
306
+ transform: translateY(-2px);
307
+ }
308
+
309
+ .theme-card[data-active] {
310
+ background-color: var(--accent-subtle);
311
+ border-color: var(--accent);
312
+ box-shadow: 0 0 0 1px var(--accent);
313
+ }
314
+
315
+ .theme-card__icon {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ inline-size: 2rem;
320
+ block-size: 2rem;
321
+ color: var(--color-text-muted);
322
+ }
323
+
324
+ .theme-card[data-active] .theme-card__icon {
325
+ color: var(--accent);
326
+ }
327
+
328
+ .theme-card__icon svg {
329
+ inline-size: 100%;
330
+ block-size: 100%;
331
+ }
332
+
333
+ .theme-card__name {
334
+ font-size: var(--font-size-sm);
335
+ font-weight: var(--weight-medium);
336
+ color: var(--color-text);
337
+ }
338
+
339
+ .theme-card__desc {
340
+ font-size: var(--font-size-xs);
341
+ color: var(--color-text-muted);
342
+ }
343
+
344
+
345
+ /* ========================================
346
+ SETTINGS ROW
347
+ Label and control side by side
348
+ ======================================== */
349
+
350
+ .settings-row {
351
+ display: flex;
352
+ align-items: center;
353
+ justify-content: space-between;
354
+ gap: var(--space-4);
355
+ padding: var(--space-2) 0;
356
+ }
357
+
358
+ .settings-row__label {
359
+ font-size: var(--font-size-sm);
360
+ color: var(--color-text);
361
+ }
362
+
363
+
364
+ /* ========================================
365
+ MODE BUTTONS (Light/Dark/Auto)
366
+ ======================================== */
367
+
368
+ .mode-buttons {
369
+ display: flex;
370
+ gap: var(--space-1);
371
+ background: var(--color-surface);
372
+ padding: var(--space-1);
373
+ border-radius: var(--radius-md);
374
+ border: 1px solid var(--color-border);
375
+ }
376
+
377
+ .mode-btn {
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ padding: var(--space-2);
382
+ border-radius: var(--radius-sm);
383
+ background: transparent;
384
+ color: var(--color-text-muted);
385
+ border: none;
386
+ cursor: pointer;
387
+ transition: all var(--duration-fast) var(--ease-fluid);
388
+ }
389
+
390
+ .mode-btn:hover {
391
+ background: var(--color-surface-raised);
392
+ color: var(--color-text);
393
+ }
394
+
395
+ .mode-btn[data-active] {
396
+ background: var(--accent);
397
+ color: var(--white);
398
+ }
399
+
400
+
401
+ /* ========================================
402
+ SETTINGS SELECT (Dropdown)
403
+ ======================================== */
404
+
405
+ .settings-select {
406
+ position: relative;
407
+ padding: var(--space-2) var(--space-3);
408
+ padding-inline-end: var(--space-8);
409
+ border-radius: var(--radius-md);
410
+ border: 1px solid var(--color-border);
411
+ background-color: var(--color-surface);
412
+ color: var(--color-text);
413
+ font-size: var(--font-size-sm);
414
+ cursor: pointer;
415
+ transition: all var(--duration-fast) var(--ease-fluid);
416
+
417
+ /* Custom arrow — CSS mask adapts to dark mode via currentColor */
418
+ appearance: none;
419
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
420
+ background-repeat: no-repeat;
421
+ background-position: right var(--space-3) center;
422
+ }
423
+
424
+ /* Dark mode: swap arrow to light color */
425
+ [data-theme="dark"] .settings-select,
426
+ .settings-select:is([data-theme="dark"] *) {
427
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
428
+ }
429
+
430
+ @media (prefers-color-scheme: dark) {
431
+ .settings-select {
432
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
433
+ }
434
+ }
435
+
436
+ .settings-select:hover {
437
+ border-color: var(--color-text-muted);
438
+ }
439
+
440
+ .settings-select:focus {
441
+ outline: 2px solid transparent;
442
+ border-color: var(--accent);
443
+ box-shadow: 0 0 0 2px var(--accent-subtle);
444
+ }
445
+
446
+
447
+ /* ========================================
448
+ PALETTE SWATCHES
449
+ ======================================== */
450
+
451
+ .palette-swatches {
452
+ display: flex;
453
+ gap: var(--space-1);
454
+ }
455
+
456
+ .palette-swatch {
457
+ inline-size: 1.5rem;
458
+ block-size: 1.5rem;
459
+ border-radius: var(--radius-full);
460
+ border: 2px solid transparent;
461
+ cursor: pointer;
462
+ transition: all var(--duration-fast) var(--ease-fluid);
463
+ position: relative;
464
+ padding: 0;
465
+ }
466
+
467
+ .palette-swatch:hover {
468
+ transform: scale(1.15);
469
+ }
470
+
471
+ .palette-swatch[data-active] {
472
+ border-color: var(--color-text);
473
+ box-shadow: 0 0 0 2px var(--color-background);
474
+ }
475
+
476
+ /* Swatch colors from CSS variables */
477
+ .palette-swatch[data-swatch="1"] { background-color: var(--palette-1); }
478
+ .palette-swatch[data-swatch="2"] { background-color: var(--palette-2); }
479
+ .palette-swatch[data-swatch="3"] { background-color: var(--palette-3); }
480
+ .palette-swatch[data-swatch="4"] { background-color: var(--palette-4); }
481
+ .palette-swatch[data-swatch="5"] { background-color: var(--palette-5); }
482
+ .palette-swatch[data-swatch="6"] { background-color: var(--palette-6); }
483
+
484
+ /* Auto indicator for fluid palette swatches */
485
+ .palette-swatch[data-auto]::after {
486
+ content: "A";
487
+ position: absolute;
488
+ inset: 0;
489
+ display: flex;
490
+ align-items: center;
491
+ justify-content: center;
492
+ font-size: 0.6rem;
493
+ font-weight: bold;
494
+ color: var(--white);
495
+ text-shadow: 0 1px 2px oklch(0% 0 0 / 0.5);
496
+ }
497
+
498
+
499
+ /* ========================================
500
+ SETTINGS HINT
501
+ ======================================== */
502
+
503
+ .settings-hint {
504
+ font-size: var(--font-size-xs);
505
+ color: var(--color-text-muted);
506
+ margin: 0;
507
+ display: none;
508
+ }
509
+
510
+ [data-palette="fluid"] .settings-hint#fluid-hint {
511
+ display: block;
512
+ }
513
+
514
+
515
+ /* ========================================
516
+ TOGGLE/SWITCH
517
+ ======================================== */
518
+
519
+ .settings-panel .switch {
520
+ position: relative;
521
+ display: inline-block;
522
+ cursor: pointer;
523
+ }
524
+
525
+ .settings-panel .switch__input {
526
+ position: absolute;
527
+ opacity: 0;
528
+ inline-size: 0;
529
+ block-size: 0;
530
+ }
531
+
532
+ .settings-panel .switch__track {
533
+ display: block;
534
+ inline-size: 2.75rem;
535
+ block-size: 1.5rem;
536
+ background-color: var(--color-border);
537
+ border-radius: var(--radius-full);
538
+ transition: background-color var(--duration-fast) var(--ease-fluid);
539
+ }
540
+
541
+ .settings-panel .switch__thumb {
542
+ position: absolute;
543
+ inset-block-start: 0.125rem;
544
+ inset-inline-start: 0.125rem;
545
+ inline-size: 1.25rem;
546
+ block-size: 1.25rem;
547
+ background-color: var(--white);
548
+ border-radius: var(--radius-full);
549
+ box-shadow: var(--shadow-sm);
550
+ transition: transform var(--duration-fast) var(--ease-settle);
551
+ }
552
+
553
+ .settings-panel .switch__input:checked + .switch__track {
554
+ background-color: var(--accent);
555
+ }
556
+
557
+ .settings-panel .switch__input:checked + .switch__track .switch__thumb {
558
+ transform: translateX(1.25rem);
559
+ }
560
+
561
+ .settings-panel .switch__input:focus-visible + .switch__track {
562
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 4px var(--accent);
563
+ }
564
+
565
+
566
+ /* ========================================
567
+ RESPONSIVE ADJUSTMENTS
568
+ ======================================== */
569
+
570
+ @media (max-width: 30rem) {
571
+ .settings-fab {
572
+ inset-block-end: var(--space-4);
573
+ inset-inline-end: var(--space-4);
574
+ }
575
+
576
+ .theme-grid {
577
+ grid-template-columns: 1fr;
578
+ }
579
+ }
580
+
581
+
582
+ /* ========================================
583
+ REDUCED MOTION
584
+ ======================================== */
585
+
586
+ @media (prefers-reduced-motion: reduce) {
587
+ .settings-drawer__panel {
588
+ transition: none;
589
+ }
590
+
591
+ .settings-drawer__backdrop {
592
+ transition: none;
593
+ }
594
+
595
+ .settings-fab {
596
+ transition: none;
597
+ }
598
+
599
+ .settings-drawer[data-open] .settings-drawer__panel {
600
+ transform: translateX(0);
601
+ }
602
+ }
603
+ }