@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,364 @@
1
+ /**
2
+ * Fluid Framework - Modal/Dialog Component
3
+ * @layer components
4
+ *
5
+ * Modal dialogs for focused interactions.
6
+ * Built on the native <dialog> element for accessibility.
7
+ * CSS-only backdrop and transitions; JS needed only for open/close.
8
+ *
9
+ * Usage:
10
+ * <dialog class="modal">
11
+ * <div class="modal__content">
12
+ * <header class="modal__header">
13
+ * <h2 class="modal__title">Title</h2>
14
+ * <button class="modal__close" aria-label="Close">&times;</button>
15
+ * </header>
16
+ * <div class="modal__body">Content here</div>
17
+ * <footer class="modal__footer">
18
+ * <button data-variant="ghost">Cancel</button>
19
+ * <button>Confirm</button>
20
+ * </footer>
21
+ * </div>
22
+ * </dialog>
23
+ *
24
+ * Sizes: data-size="sm|lg|full"
25
+ * Variants: data-variant="centered|drawer-right|drawer-left"
26
+ *
27
+ * JS API:
28
+ * dialog.showModal() — open with backdrop
29
+ * dialog.close() — close
30
+ */
31
+
32
+ @layer components {
33
+ /* ========================================
34
+ BASE MODAL (native <dialog>)
35
+ ======================================== */
36
+
37
+ .modal {
38
+ /* Reset dialog defaults */
39
+ border: none;
40
+ padding: 0;
41
+ max-inline-size: none;
42
+ max-block-size: none;
43
+ background: transparent;
44
+ color: var(--color-text);
45
+ overflow: visible;
46
+
47
+ /* Full viewport overlay */
48
+ position: fixed;
49
+ inset: 0;
50
+ inline-size: 100%;
51
+ block-size: 100%;
52
+ z-index: var(--z-modal);
53
+
54
+ /* Center the content by default */
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ padding: var(--space-5);
59
+
60
+ /* Closed state */
61
+ opacity: 0;
62
+ visibility: hidden;
63
+ pointer-events: none;
64
+
65
+ /* Transition */
66
+ transition:
67
+ opacity var(--duration-normal) var(--ease-fluid),
68
+ visibility var(--duration-normal) var(--ease-fluid);
69
+ }
70
+
71
+ /* Open state */
72
+ .modal[open] {
73
+ opacity: 1;
74
+ visibility: visible;
75
+ pointer-events: auto;
76
+ }
77
+
78
+ /* Native backdrop */
79
+ .modal::backdrop {
80
+ background: oklch(0% 0 0 / 0.5);
81
+ backdrop-filter: blur(4px);
82
+ }
83
+
84
+
85
+ /* ========================================
86
+ MODAL CONTENT PANEL
87
+ ======================================== */
88
+
89
+ .modal__content {
90
+ --_modal-width: min(90vw, 32rem);
91
+
92
+ position: relative;
93
+ display: flex;
94
+ flex-direction: column;
95
+ inline-size: var(--_modal-width);
96
+ max-block-size: min(90vh, 40rem);
97
+
98
+ background: var(--color-surface-raised);
99
+ border: var(--border-width) solid var(--color-border-subtle);
100
+ border-radius: var(--radius-2xl);
101
+ box-shadow: var(--shadow-xl);
102
+ overflow: hidden;
103
+
104
+ /* Entry animation */
105
+ transform: translateY(var(--space-5)) scale(0.97);
106
+ transition:
107
+ transform var(--duration-normal) var(--ease-settle);
108
+ }
109
+
110
+ .modal[open] .modal__content {
111
+ transform: translateY(0) scale(1);
112
+ }
113
+
114
+
115
+ /* ========================================
116
+ MODAL SECTIONS
117
+ ======================================== */
118
+
119
+ .modal__header {
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: space-between;
123
+ gap: var(--space-4);
124
+ padding: var(--space-5) var(--space-6);
125
+ border-block-end: var(--border-width) solid var(--color-border-subtle);
126
+ flex-shrink: 0;
127
+ }
128
+
129
+ .modal__title {
130
+ font-size: var(--font-size-lg);
131
+ font-weight: var(--weight-semibold);
132
+ line-height: var(--leading-tight);
133
+ margin: 0;
134
+ }
135
+
136
+ .modal__close {
137
+ --_btn-bg: transparent;
138
+ --_btn-shadow: none;
139
+
140
+ position: relative;
141
+ flex-shrink: 0;
142
+ display: inline-flex;
143
+ align-items: center;
144
+ justify-content: center;
145
+ inline-size: 2.75rem;
146
+ block-size: 2.75rem;
147
+ padding: 0;
148
+ border-radius: var(--radius-md);
149
+ font-size: var(--font-size-xl);
150
+ line-height: 1;
151
+ color: var(--color-text-muted);
152
+ cursor: pointer;
153
+ transition: color var(--duration-fast) var(--ease-fluid),
154
+ background-color var(--duration-fast) var(--ease-fluid);
155
+ }
156
+
157
+ .modal__close:hover {
158
+ color: var(--color-text);
159
+ background-color: var(--color-surface);
160
+ }
161
+
162
+ .modal__body {
163
+ flex: 1;
164
+ padding: var(--space-6);
165
+ overflow-y: auto;
166
+ overscroll-behavior: contain;
167
+ }
168
+
169
+ .modal__footer {
170
+ display: flex;
171
+ align-items: center;
172
+ justify-content: flex-end;
173
+ gap: var(--space-3);
174
+ padding: var(--space-4) var(--space-6);
175
+ border-block-start: var(--border-width) solid var(--color-border-subtle);
176
+ flex-shrink: 0;
177
+ }
178
+
179
+
180
+ /* ========================================
181
+ SIZE VARIANTS
182
+ ======================================== */
183
+
184
+ /* Small - alerts, confirmations */
185
+ .modal[data-size="sm"] .modal__content {
186
+ --_modal-width: min(90vw, 24rem);
187
+ }
188
+
189
+ /* Large - forms, complex content */
190
+ .modal[data-size="lg"] .modal__content {
191
+ --_modal-width: min(90vw, 48rem);
192
+ max-block-size: min(90vh, 50rem);
193
+ }
194
+
195
+ /* Full - immersive experiences */
196
+ .modal[data-size="full"] .modal__content {
197
+ --_modal-width: min(95vw, 72rem);
198
+ max-block-size: 95vh;
199
+ }
200
+
201
+
202
+ /* ========================================
203
+ DRAWER VARIANTS
204
+ Slide in from edges
205
+ ======================================== */
206
+
207
+ /* Right drawer */
208
+ .modal[data-variant="drawer-right"] {
209
+ justify-content: flex-end;
210
+ padding: 0;
211
+ }
212
+
213
+ .modal[data-variant="drawer-right"] .modal__content {
214
+ --_modal-width: min(90vw, 28rem);
215
+ max-block-size: 100vh;
216
+ block-size: 100vh;
217
+ border-radius: var(--radius-2xl) 0 0 var(--radius-2xl);
218
+ transform: translateX(100%);
219
+ }
220
+
221
+ .modal[data-variant="drawer-right"][open] .modal__content {
222
+ transform: translateX(0);
223
+ }
224
+
225
+ /* Left drawer */
226
+ .modal[data-variant="drawer-left"] {
227
+ justify-content: flex-start;
228
+ padding: 0;
229
+ }
230
+
231
+ .modal[data-variant="drawer-left"] .modal__content {
232
+ --_modal-width: min(90vw, 28rem);
233
+ max-block-size: 100vh;
234
+ block-size: 100vh;
235
+ border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0;
236
+ transform: translateX(-100%);
237
+ }
238
+
239
+ .modal[data-variant="drawer-left"][open] .modal__content {
240
+ transform: translateX(0);
241
+ }
242
+
243
+
244
+ /* ========================================
245
+ DESTRUCTIVE CONFIRMATION MODIFIER
246
+ Wider gap in footer, mobile stacking
247
+ ======================================== */
248
+
249
+ .modal[data-destructive] .modal__footer {
250
+ gap: var(--space-5);
251
+ }
252
+
253
+ @media (max-width: 40rem) {
254
+ .modal[data-destructive] .modal__footer {
255
+ flex-direction: column-reverse;
256
+ }
257
+
258
+ .modal[data-destructive] .modal__footer > button {
259
+ inline-size: 100%;
260
+ }
261
+ }
262
+
263
+
264
+ /* ========================================
265
+ THEME-SPECIFIC MODAL STYLES
266
+ ======================================== */
267
+
268
+ /* Still: sharp, no animation */
269
+ [data-motion="still"] .modal__content {
270
+ border-radius: var(--radius-md);
271
+ transform: none;
272
+ transition: none;
273
+ }
274
+
275
+ [data-motion="still"] .modal {
276
+ transition: none;
277
+ }
278
+
279
+ /* Serene: gentle, pillowy */
280
+ [data-motion="serene"] .modal__content {
281
+ border-radius: var(--radius-2xl);
282
+ box-shadow: var(--shadow-lg);
283
+ }
284
+
285
+ /* Cascade: bouncy entry */
286
+ [data-motion="cascade"] .modal__content {
287
+ border-radius: var(--radius-2xl);
288
+ }
289
+
290
+ /* Rapids: hard offset shadow */
291
+ [data-motion="rapids"] .modal__content {
292
+ box-shadow: var(--shadow-offset-hover);
293
+ }
294
+
295
+ /* Tsunami: dramatic, asymmetric corners */
296
+ [data-motion="tsunami"] .modal__content {
297
+ border-radius: var(--radius-asymmetric-lg, 0 48px 0 0);
298
+ box-shadow: var(--shadow-xl);
299
+ }
300
+
301
+
302
+ /* ========================================
303
+ RESPONSIVE
304
+ ======================================== */
305
+
306
+ @media (max-width: 40rem) {
307
+ .modal {
308
+ padding: var(--space-3);
309
+ align-items: flex-end;
310
+ }
311
+
312
+ .modal__content {
313
+ --_modal-width: 100%;
314
+ max-block-size: 85vh;
315
+ border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
316
+ transform: translateY(100%);
317
+ }
318
+
319
+ .modal[open] .modal__content {
320
+ transform: translateY(0);
321
+ }
322
+
323
+ /* Drawers become bottom sheet on mobile */
324
+ .modal[data-variant="drawer-right"],
325
+ .modal[data-variant="drawer-left"] {
326
+ justify-content: center;
327
+ align-items: flex-end;
328
+ padding: 0;
329
+ }
330
+
331
+ .modal[data-variant="drawer-right"] .modal__content,
332
+ .modal[data-variant="drawer-left"] .modal__content {
333
+ block-size: auto;
334
+ max-block-size: 85vh;
335
+ border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
336
+ transform: translateY(100%);
337
+ }
338
+
339
+ .modal[data-variant="drawer-right"][open] .modal__content,
340
+ .modal[data-variant="drawer-left"][open] .modal__content {
341
+ transform: translateY(0);
342
+ }
343
+ }
344
+
345
+
346
+ /* ========================================
347
+ REDUCED MOTION
348
+ ======================================== */
349
+
350
+ @media (prefers-reduced-motion: reduce) {
351
+ .modal {
352
+ transition: none;
353
+ }
354
+
355
+ .modal__content {
356
+ transform: none;
357
+ transition: none;
358
+ }
359
+
360
+ .modal[open] .modal__content {
361
+ transform: none;
362
+ }
363
+ }
364
+ }