@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,192 @@
1
+ /**
2
+ * Fluid Framework - Avatar Component
3
+ * @layer components
4
+ *
5
+ * Avatars display user profile images or initials.
6
+ * Supports sizes, groups, status indicators, and fallbacks.
7
+ *
8
+ * Usage:
9
+ * <div class="avatar">
10
+ * <img src="photo.jpg" alt="Jane Doe">
11
+ * </div>
12
+ *
13
+ * <!-- With initials fallback -->
14
+ * <div class="avatar" data-initials="JD"></div>
15
+ *
16
+ * <!-- With status -->
17
+ * <div class="avatar" data-status="online">
18
+ * <img src="photo.jpg" alt="Jane Doe">
19
+ * </div>
20
+ *
21
+ * Sizes: data-size="xs|sm|lg|xl|2xl"
22
+ * Shapes: data-shape="square|rounded" (default: circle)
23
+ * Groups: <div class="avatar-group">...</div>
24
+ */
25
+
26
+ @layer components {
27
+ /* ========================================
28
+ BASE AVATAR
29
+ ======================================== */
30
+
31
+ .avatar {
32
+ --_avatar-size: 2.5rem;
33
+
34
+ position: relative;
35
+ display: inline-flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ flex-shrink: 0;
39
+ inline-size: var(--_avatar-size);
40
+ block-size: var(--_avatar-size);
41
+ border-radius: var(--radius-full);
42
+ background: color-mix(in oklch, var(--accent) 20%, var(--color-surface));
43
+ color: var(--accent);
44
+ font-weight: var(--weight-semibold);
45
+ font-size: calc(var(--_avatar-size) * 0.4);
46
+ line-height: 1;
47
+ overflow: visible;
48
+ user-select: none;
49
+ }
50
+
51
+ /* Image inside avatar */
52
+ .avatar img {
53
+ inline-size: 100%;
54
+ block-size: 100%;
55
+ object-fit: cover;
56
+ border-radius: inherit;
57
+ }
58
+
59
+ /* Initials fallback (when no image) */
60
+ .avatar[data-initials]::before {
61
+ content: attr(data-initials);
62
+ text-transform: uppercase;
63
+ letter-spacing: var(--tracking-wide);
64
+ }
65
+
66
+ /* Border ring */
67
+ .avatar[data-ring] {
68
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 4px var(--accent);
69
+ }
70
+
71
+
72
+ /* ========================================
73
+ SIZE VARIANTS
74
+ ======================================== */
75
+
76
+ .avatar[data-size="xs"] { --_avatar-size: 1.5rem; }
77
+ .avatar[data-size="sm"] { --_avatar-size: 2rem; }
78
+ /* default: 2.5rem */
79
+ .avatar[data-size="lg"] { --_avatar-size: 3rem; }
80
+ .avatar[data-size="xl"] { --_avatar-size: 4rem; }
81
+ .avatar[data-size="2xl"] { --_avatar-size: 5rem; }
82
+
83
+
84
+ /* ========================================
85
+ SHAPE VARIANTS
86
+ ======================================== */
87
+
88
+ .avatar[data-shape="square"] {
89
+ border-radius: var(--radius-md);
90
+ }
91
+
92
+ .avatar[data-shape="rounded"] {
93
+ border-radius: var(--radius-lg);
94
+ }
95
+
96
+
97
+ /* ========================================
98
+ STATUS INDICATOR
99
+ ======================================== */
100
+
101
+ .avatar[data-status]::after {
102
+ content: "";
103
+ position: absolute;
104
+ inset-block-end: 0;
105
+ inset-inline-end: 0;
106
+ inline-size: calc(var(--_avatar-size) * 0.3);
107
+ block-size: calc(var(--_avatar-size) * 0.3);
108
+ border-radius: var(--radius-full);
109
+ border: 2px solid var(--color-background);
110
+ background: var(--color-text-subtle);
111
+ }
112
+
113
+ .avatar[data-status="online"]::after {
114
+ background: var(--color-success);
115
+ }
116
+
117
+ .avatar[data-status="busy"]::after {
118
+ background: var(--color-error);
119
+ }
120
+
121
+ .avatar[data-status="away"]::after {
122
+ background: var(--color-warning);
123
+ }
124
+
125
+ .avatar[data-status="offline"]::after {
126
+ background: var(--color-text-subtle);
127
+ }
128
+
129
+ /* Don't show status dot on initials-only avatars unless explicitly set */
130
+ .avatar[data-initials]:not([data-status])::after {
131
+ display: none;
132
+ }
133
+
134
+
135
+ /* ========================================
136
+ AVATAR GROUP
137
+ Overlapping stack
138
+ ======================================== */
139
+
140
+ .avatar-group {
141
+ display: flex;
142
+ align-items: center;
143
+ }
144
+
145
+ .avatar-group .avatar {
146
+ box-shadow: 0 0 0 2px var(--color-background);
147
+ transition: transform var(--duration-fast) var(--ease-settle);
148
+ }
149
+
150
+ .avatar-group .avatar + .avatar {
151
+ margin-inline-start: calc(var(--_avatar-size) * -0.3);
152
+ }
153
+
154
+ .avatar-group .avatar:hover {
155
+ z-index: var(--z-raised);
156
+ transform: scale(1.1);
157
+ }
158
+
159
+ /* Overflow counter: +5 more */
160
+ .avatar-group__overflow {
161
+ --_avatar-size: 2.5rem;
162
+
163
+ display: inline-flex;
164
+ align-items: center;
165
+ justify-content: center;
166
+ inline-size: var(--_avatar-size);
167
+ block-size: var(--_avatar-size);
168
+ border-radius: var(--radius-full);
169
+ background: var(--color-surface);
170
+ border: var(--border-width) solid var(--color-border-subtle);
171
+ font-size: var(--font-size-xs);
172
+ font-weight: var(--weight-semibold);
173
+ color: var(--color-text-muted);
174
+ margin-inline-start: calc(var(--_avatar-size) * -0.3);
175
+ box-shadow: 0 0 0 2px var(--color-background);
176
+ }
177
+
178
+
179
+ /* ========================================
180
+ THEME-SPECIFIC STYLES
181
+ ======================================== */
182
+
183
+ /* Tsunami: asymmetric corners on square */
184
+ [data-motion="tsunami"] .avatar[data-shape="square"] {
185
+ border-radius: var(--radius-asymmetric, 0 12px 0 0);
186
+ }
187
+
188
+ /* Rapids: hard shadow on group */
189
+ [data-motion="rapids"] .avatar-group .avatar {
190
+ box-shadow: 2px 2px 0 oklch(0 0 0 / 0.1), 0 0 0 2px var(--color-background);
191
+ }
192
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Fluid Framework - Badge Component
3
+ * @layer components
4
+ *
5
+ * Small labels for status, categories, counts, and metadata.
6
+ * Works standalone or positioned inside cards and other components.
7
+ *
8
+ * Usage:
9
+ * <span class="badge">Default</span>
10
+ * <span class="badge" data-variant="filled">Filled</span>
11
+ * <span class="badge" data-variant="outline">Outline</span>
12
+ * <span class="badge" data-status="good">Active</span>
13
+ * <span class="badge" data-status="warning">Pending</span>
14
+ * <span class="badge" data-status="error">Failed</span>
15
+ * <span class="badge" data-size="sm">Small</span>
16
+ * <span class="badge" data-size="lg">Large</span>
17
+ */
18
+
19
+ @layer components {
20
+ /* ========================================
21
+ BASE BADGE
22
+ ======================================== */
23
+
24
+ .badge {
25
+ display: inline-flex;
26
+ align-items: center;
27
+ gap: var(--space-1);
28
+ padding: var(--space-1) var(--space-3);
29
+ font-size: var(--font-size-xs);
30
+ font-weight: var(--weight-semibold);
31
+ line-height: var(--leading-tight);
32
+ letter-spacing: var(--tracking-wide);
33
+ text-transform: uppercase;
34
+ border-radius: var(--radius-full);
35
+ white-space: nowrap;
36
+ vertical-align: middle;
37
+
38
+ /* Default: accent-tinted */
39
+ color: var(--accent);
40
+ background: var(--accent-subtle);
41
+ }
42
+
43
+
44
+ /* ========================================
45
+ VARIANTS
46
+ ======================================== */
47
+
48
+ /* Filled - solid accent background */
49
+ .badge[data-variant="filled"] {
50
+ color: var(--white);
51
+ background: var(--accent);
52
+ }
53
+
54
+ /* Outline - border only */
55
+ .badge[data-variant="outline"] {
56
+ background: transparent;
57
+ border: var(--border-width) solid currentColor;
58
+ }
59
+
60
+ /* Muted - subtle neutral tones */
61
+ .badge[data-variant="muted"] {
62
+ color: var(--color-text-muted);
63
+ background: var(--color-surface);
64
+ }
65
+
66
+
67
+ /* ========================================
68
+ STATUS COLORS
69
+ Semantic states for indicators
70
+ ======================================== */
71
+
72
+ .badge[data-status="good"] {
73
+ color: var(--color-success);
74
+ background: var(--color-success-subtle);
75
+ }
76
+
77
+ .badge[data-status="warning"] {
78
+ color: var(--color-warning);
79
+ background: var(--color-warning-subtle);
80
+ }
81
+
82
+ .badge[data-status="error"] {
83
+ color: var(--color-error);
84
+ background: var(--color-error-subtle);
85
+ }
86
+
87
+ .badge[data-status="info"] {
88
+ color: var(--color-info);
89
+ background: var(--color-info-subtle);
90
+ }
91
+
92
+ /* Status + filled combo */
93
+ .badge[data-status="good"][data-variant="filled"] {
94
+ color: var(--white);
95
+ background: var(--color-success);
96
+ }
97
+
98
+ .badge[data-status="warning"][data-variant="filled"] {
99
+ color: var(--white);
100
+ background: var(--color-warning);
101
+ }
102
+
103
+ .badge[data-status="error"][data-variant="filled"] {
104
+ color: var(--white);
105
+ background: var(--color-error);
106
+ }
107
+
108
+ .badge[data-status="info"][data-variant="filled"] {
109
+ color: var(--white);
110
+ background: var(--color-info);
111
+ }
112
+
113
+
114
+ /* ========================================
115
+ SIZES
116
+ ======================================== */
117
+
118
+ .badge[data-size="sm"] {
119
+ padding: var(--space-0-5) var(--space-2);
120
+ font-size: var(--font-size-2xs, 0.6875rem);
121
+ letter-spacing: var(--tracking-wider);
122
+ }
123
+
124
+ .badge[data-size="lg"] {
125
+ padding: var(--space-2) var(--space-4);
126
+ font-size: var(--font-size-sm);
127
+ }
128
+
129
+
130
+ /* ========================================
131
+ BADGE WITH DOT
132
+ Status dot indicator before text
133
+ ======================================== */
134
+
135
+ .badge[data-dot]::before {
136
+ content: "";
137
+ inline-size: 0.375rem;
138
+ block-size: 0.375rem;
139
+ border-radius: var(--radius-full);
140
+ background: currentColor;
141
+ flex-shrink: 0;
142
+ }
143
+
144
+
145
+ /* ========================================
146
+ BADGE COUNT
147
+ Numeric counters (notifications, etc.)
148
+ ======================================== */
149
+
150
+ .badge[data-count] {
151
+ min-inline-size: 1.5rem;
152
+ justify-content: center;
153
+ padding: var(--space-1);
154
+ border-radius: var(--radius-full);
155
+ font-variant-numeric: tabular-nums;
156
+ }
157
+
158
+
159
+ /* ========================================
160
+ THEME-SPECIFIC STYLES
161
+ ======================================== */
162
+
163
+ /* Still: square badges */
164
+ [data-motion="still"] .badge {
165
+ border-radius: 0;
166
+ letter-spacing: var(--tracking-wider);
167
+ }
168
+
169
+ /* Brutalist: hard edges, bold */
170
+ [data-motion="brutalist"] .badge {
171
+ border-radius: 0;
172
+ text-transform: uppercase;
173
+ font-weight: var(--weight-bold);
174
+ border: 2px solid currentColor;
175
+ background: transparent;
176
+ }
177
+
178
+ /* Tsunami: asymmetric corners */
179
+ [data-motion="tsunami"] .badge {
180
+ border-radius: var(--radius-asymmetric, 0 12px 0 0);
181
+ }
182
+ }