fernwell 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,1548 @@
1
+ /*! fernwell v0.1.0 | MIT | https://github.com/JacobKnaack/fernwell */
2
+ /* src/css/tokens.css */
3
+ @layer fw-tokens {
4
+ :root,
5
+ [data-theme=light] {
6
+ --fw-text: #1F2430;
7
+ --fw-text-soft: #565D6E;
8
+ --fw-bg: #F5F6F1;
9
+ --fw-bg-dim: #EAEBE4;
10
+ --fw-surface: #FFFFFF;
11
+ --fw-primary: #FFC145;
12
+ --fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);
13
+ --fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);
14
+ --fw-secondary: #4C3A73;
15
+ --fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);
16
+ --fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 10%, var(--fw-surface));
17
+ --fw-success: #3FA672;
18
+ --fw-success-bg: color-mix(in srgb, var(--fw-success) 12%, var(--fw-surface));
19
+ --fw-warning: #E8A521;
20
+ --fw-warning-bg: color-mix(in srgb, var(--fw-warning) 14%, var(--fw-surface));
21
+ --fw-danger: #E85B4F;
22
+ --fw-danger-bg: color-mix(in srgb, var(--fw-danger) 13%, var(--fw-surface));
23
+ --fw-info: #3E8FD0;
24
+ --fw-info-bg: color-mix(in srgb, var(--fw-info) 12%, var(--fw-surface));
25
+ --fw-on-primary: #1F2430;
26
+ --fw-on-secondary: #FFFFFF;
27
+ --fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);
28
+ --fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);
29
+ --fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);
30
+ --fw-overlay: rgba(31, 36, 48, 0.55);
31
+ --fw-overlay-soft: rgba(31, 36, 48, 0.32);
32
+ --fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);
33
+ --fw-font-display:
34
+ "Plus Jakarta Sans",
35
+ system-ui,
36
+ sans-serif;
37
+ --fw-font-body:
38
+ "Inter",
39
+ system-ui,
40
+ sans-serif;
41
+ --fw-font-mono:
42
+ "IBM Plex Mono",
43
+ ui-monospace,
44
+ SFMono-Regular,
45
+ Menlo,
46
+ monospace;
47
+ --fw-sp-1: 4px;
48
+ --fw-sp-2: 8px;
49
+ --fw-sp-3: 12px;
50
+ --fw-sp-4: 16px;
51
+ --fw-sp-5: 24px;
52
+ --fw-sp-6: 32px;
53
+ --fw-sp-7: 48px;
54
+ --fw-sp-8: 64px;
55
+ --fw-sp-9: 96px;
56
+ --fw-r-sm: 10px;
57
+ --fw-r-md: 16px;
58
+ --fw-r-lg: 24px;
59
+ --fw-r-xl: 32px;
60
+ --fw-r-full: 999px;
61
+ --fw-shadow-sm: 0 1px 2px rgba(31, 36, 48, 0.06), 0 1px 1px rgba(31, 36, 48, 0.04);
62
+ --fw-shadow-md: 0 4px 12px rgba(31, 36, 48, 0.08), 0 2px 4px rgba(31, 36, 48, 0.04);
63
+ --fw-shadow-lg: 0 12px 32px rgba(31, 36, 48, 0.12), 0 4px 8px rgba(31, 36, 48, 0.06);
64
+ --fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 35%, transparent);
65
+ --fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 28%, transparent);
66
+ --fw-border-w: 1.5px;
67
+ --fw-motion-fast: 120ms;
68
+ --fw-motion-base: 180ms;
69
+ --fw-motion-ease: ease;
70
+ }
71
+ [data-theme=dark] {
72
+ --fw-text: #F2F1EA;
73
+ --fw-text-soft: #9CA1B0;
74
+ --fw-bg: #14161C;
75
+ --fw-bg-dim: #2B2F3B;
76
+ --fw-surface: #1D2029;
77
+ --fw-primary: #FFC145;
78
+ --fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);
79
+ --fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);
80
+ --fw-secondary: #6B54A3;
81
+ --fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);
82
+ --fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 16%, transparent);
83
+ --fw-success: #55D194;
84
+ --fw-success-bg: color-mix(in srgb, var(--fw-success) 14%, transparent);
85
+ --fw-warning: #FFD166;
86
+ --fw-warning-bg: color-mix(in srgb, var(--fw-warning) 16%, transparent);
87
+ --fw-danger: #FF8478;
88
+ --fw-danger-bg: color-mix(in srgb, var(--fw-danger) 14%, transparent);
89
+ --fw-info: #6BB3E8;
90
+ --fw-info-bg: color-mix(in srgb, var(--fw-info) 14%, transparent);
91
+ --fw-on-primary: #1F2430;
92
+ --fw-on-secondary: #FFFFFF;
93
+ --fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);
94
+ --fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);
95
+ --fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);
96
+ --fw-overlay: rgba(0, 0, 0, 0.6);
97
+ --fw-overlay-soft: rgba(0, 0, 0, 0.4);
98
+ --fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);
99
+ --fw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
100
+ --fw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35);
101
+ --fw-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.45);
102
+ --fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 22%, transparent);
103
+ --fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 22%, transparent);
104
+ }
105
+ }
106
+
107
+ /* src/css/base.css */
108
+ .fw-root {
109
+ background: var(--fw-bg);
110
+ color: var(--fw-text);
111
+ font-family: var(--fw-font-body);
112
+ line-height: 1.5;
113
+ -webkit-font-smoothing: antialiased;
114
+ transition: background var(--fw-motion-base) var(--fw-motion-ease), color var(--fw-motion-base) var(--fw-motion-ease);
115
+ }
116
+ .fw-root,
117
+ .fw-root *,
118
+ .fw-root *::before,
119
+ .fw-root *::after {
120
+ box-sizing: border-box;
121
+ }
122
+ .fw-root :where(h1, h2, h3, h4) {
123
+ font-family: var(--fw-font-display);
124
+ color: var(--fw-text);
125
+ margin: 0;
126
+ }
127
+ .fw-root :where(p) {
128
+ margin: 0;
129
+ }
130
+ .fw-root :where(a) {
131
+ color: inherit;
132
+ }
133
+ .fw-root :where(code) {
134
+ font-family: var(--fw-font-mono);
135
+ }
136
+ [hidden] {
137
+ display: none !important;
138
+ }
139
+ .fw-sr-only {
140
+ position: absolute;
141
+ width: 1px;
142
+ height: 1px;
143
+ padding: 0;
144
+ margin: -1px;
145
+ overflow: hidden;
146
+ clip: rect(0, 0, 0, 0);
147
+ white-space: nowrap;
148
+ border: 0;
149
+ }
150
+ .fw-scroll-lock {
151
+ overflow: hidden;
152
+ }
153
+ @media (prefers-reduced-motion: reduce) {
154
+ .fw-root {
155
+ scroll-behavior: auto;
156
+ }
157
+ .fw-btn,
158
+ .fw-btn:hover,
159
+ .fw-list-row,
160
+ .fw-list-row:hover {
161
+ transform: none;
162
+ }
163
+ }
164
+
165
+ /* src/css/components/layout.css */
166
+ .fw-wrap {
167
+ max-width: 1100px;
168
+ margin: 0 auto;
169
+ padding: 0 var(--fw-sp-5);
170
+ }
171
+ .fw-row {
172
+ display: flex;
173
+ gap: var(--fw-sp-4);
174
+ flex-wrap: wrap;
175
+ align-items: center;
176
+ }
177
+ .fw-grid-2 {
178
+ display: grid;
179
+ grid-template-columns: 1fr 1fr;
180
+ gap: var(--fw-sp-5);
181
+ }
182
+ @media (max-width: 640px) {
183
+ .fw-grid-2 {
184
+ grid-template-columns: 1fr;
185
+ }
186
+ }
187
+
188
+ /* src/css/components/button.css */
189
+ .fw-btn {
190
+ font-family: var(--fw-font-body);
191
+ font-weight: 700;
192
+ font-size: 15px;
193
+ line-height: 1.2;
194
+ border-radius: var(--fw-r-md);
195
+ padding: 12px 22px;
196
+ border: none;
197
+ cursor: pointer;
198
+ display: inline-flex;
199
+ align-items: center;
200
+ gap: var(--fw-sp-2);
201
+ text-decoration: none;
202
+ transition:
203
+ transform var(--fw-motion-fast) var(--fw-motion-ease),
204
+ box-shadow var(--fw-motion-fast) var(--fw-motion-ease),
205
+ background var(--fw-motion-fast) var(--fw-motion-ease),
206
+ border-color var(--fw-motion-fast) var(--fw-motion-ease);
207
+ }
208
+ .fw-btn:hover {
209
+ transform: translateY(-1px);
210
+ }
211
+ .fw-btn:active {
212
+ transform: translateY(0);
213
+ }
214
+ .fw-btn:focus-visible {
215
+ outline: none;
216
+ box-shadow: var(--fw-focus-ring);
217
+ }
218
+ .fw-btn-primary {
219
+ background: var(--fw-primary);
220
+ color: var(--fw-on-primary);
221
+ box-shadow: var(--fw-shadow-primary);
222
+ }
223
+ .fw-btn-primary:hover {
224
+ background: var(--fw-primary-hover);
225
+ }
226
+ .fw-btn-secondary {
227
+ background: var(--fw-secondary);
228
+ color: var(--fw-on-secondary);
229
+ }
230
+ .fw-btn-secondary:hover {
231
+ background: var(--fw-secondary-hover);
232
+ }
233
+ .fw-btn-ghost {
234
+ background: transparent;
235
+ color: var(--fw-text);
236
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
237
+ }
238
+ .fw-btn-ghost:hover {
239
+ border-color: var(--fw-text-soft);
240
+ }
241
+ .fw-btn-danger {
242
+ background: var(--fw-danger-bg);
243
+ color: var(--fw-danger);
244
+ }
245
+ .fw-btn-lg {
246
+ padding: 14px 26px;
247
+ }
248
+ .fw-btn:disabled,
249
+ .fw-btn[aria-disabled=true] {
250
+ opacity: 0.45;
251
+ cursor: not-allowed;
252
+ transform: none;
253
+ }
254
+ .fw-btn-loading {
255
+ cursor: progress;
256
+ }
257
+ .fw-btn .fw-spinner {
258
+ margin-right: 2px;
259
+ }
260
+ .fw-icon-btn {
261
+ width: 32px;
262
+ height: 32px;
263
+ border-radius: var(--fw-r-sm);
264
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
265
+ background: var(--fw-surface);
266
+ display: inline-flex;
267
+ align-items: center;
268
+ justify-content: center;
269
+ cursor: pointer;
270
+ color: var(--fw-text-soft);
271
+ flex-shrink: 0;
272
+ padding: 0;
273
+ text-decoration: none;
274
+ transition: border-color var(--fw-motion-fast) var(--fw-motion-ease), color var(--fw-motion-fast) var(--fw-motion-ease);
275
+ }
276
+ .fw-icon-btn:hover {
277
+ border-color: var(--fw-secondary);
278
+ color: var(--fw-secondary);
279
+ }
280
+ .fw-icon-btn:focus-visible {
281
+ outline: none;
282
+ box-shadow: var(--fw-focus-ring);
283
+ }
284
+ .fw-icon-btn svg {
285
+ width: 15px;
286
+ height: 15px;
287
+ }
288
+
289
+ /* src/css/components/card.css */
290
+ .fw-card {
291
+ background: var(--fw-surface);
292
+ border-radius: var(--fw-r-lg);
293
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
294
+ box-shadow: var(--fw-shadow-sm);
295
+ padding: var(--fw-sp-5);
296
+ color: var(--fw-text);
297
+ }
298
+
299
+ /* src/css/components/tag.css */
300
+ .fw-tag {
301
+ display: inline-flex;
302
+ align-items: center;
303
+ gap: 6px;
304
+ font-family: var(--fw-font-mono);
305
+ font-size: 12px;
306
+ font-weight: 600;
307
+ line-height: 1.3;
308
+ padding: 5px 12px;
309
+ border-radius: var(--fw-r-md);
310
+ transform: rotate(-2deg);
311
+ background: var(--fw-bg-dim);
312
+ color: var(--fw-text-soft);
313
+ white-space: nowrap;
314
+ }
315
+ .fw-tag:nth-of-type(2n) {
316
+ transform: rotate(1.5deg);
317
+ }
318
+ .fw-tag:nth-of-type(3n) {
319
+ transform: rotate(-1deg);
320
+ }
321
+ .fw-tag-pill,
322
+ .fw-tag-pill:nth-of-type(n) {
323
+ transform: none;
324
+ font-size: 11px;
325
+ padding: 4px 10px;
326
+ border-radius: var(--fw-r-full);
327
+ }
328
+ .fw-tag-live {
329
+ background: var(--fw-success-bg);
330
+ color: var(--fw-success);
331
+ }
332
+ .fw-tag-live::before {
333
+ content: "";
334
+ width: 6px;
335
+ height: 6px;
336
+ border-radius: 50%;
337
+ background: var(--fw-success);
338
+ }
339
+ .fw-tag-pending {
340
+ background: var(--fw-warning-bg);
341
+ color: var(--fw-warning);
342
+ }
343
+ .fw-tag-error {
344
+ background: var(--fw-danger-bg);
345
+ color: var(--fw-danger);
346
+ }
347
+ .fw-tag-info {
348
+ background: var(--fw-info-bg);
349
+ color: var(--fw-info);
350
+ }
351
+ .fw-tag-secondary {
352
+ background: var(--fw-secondary-bg);
353
+ color: var(--fw-secondary);
354
+ }
355
+ @media (prefers-reduced-motion: no-preference) {
356
+ .fw-tag {
357
+ transition: transform var(--fw-motion-fast) var(--fw-motion-ease);
358
+ }
359
+ }
360
+
361
+ /* src/css/components/eyebrow.css */
362
+ .fw-eyebrow {
363
+ display: inline-flex;
364
+ align-items: center;
365
+ gap: var(--fw-sp-2);
366
+ font-family: var(--fw-font-mono);
367
+ font-size: 12px;
368
+ font-weight: 600;
369
+ letter-spacing: 0.08em;
370
+ text-transform: uppercase;
371
+ color: var(--fw-secondary);
372
+ background: var(--fw-surface);
373
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
374
+ padding: 7px 16px;
375
+ border-radius: var(--fw-r-full);
376
+ box-shadow: var(--fw-shadow-sm);
377
+ }
378
+ .fw-eyebrow::before {
379
+ content: "";
380
+ width: 6px;
381
+ height: 6px;
382
+ border-radius: 50%;
383
+ background: var(--fw-primary);
384
+ }
385
+ [data-theme=dark] .fw-eyebrow {
386
+ color: var(--fw-secondary-hover);
387
+ }
388
+
389
+ /* src/css/components/field.css */
390
+ .fw-field {
391
+ display: flex;
392
+ flex-direction: column;
393
+ gap: 6px;
394
+ max-width: 320px;
395
+ }
396
+ .fw-field-full {
397
+ max-width: none;
398
+ }
399
+ .fw-label,
400
+ .fw-field > label {
401
+ font-size: 13px;
402
+ font-weight: 600;
403
+ color: var(--fw-text);
404
+ }
405
+ .fw-hint {
406
+ font-size: 12px;
407
+ color: var(--fw-text-soft);
408
+ }
409
+ .fw-error-msg {
410
+ font-size: 12px;
411
+ color: var(--fw-danger);
412
+ font-weight: 600;
413
+ }
414
+ .fw-required {
415
+ color: var(--fw-danger);
416
+ font-weight: 700;
417
+ margin-left: 3px;
418
+ }
419
+ .fw-input,
420
+ .fw-field input:not([type=checkbox]):not([type=radio]),
421
+ .fw-field select,
422
+ .fw-field textarea {
423
+ font-family: var(--fw-font-body);
424
+ font-size: 15px;
425
+ line-height: 1.4;
426
+ padding: 11px 14px;
427
+ border-radius: var(--fw-r-sm);
428
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
429
+ background: var(--fw-surface);
430
+ color: var(--fw-text);
431
+ outline: none;
432
+ width: 100%;
433
+ transition:
434
+ border-color var(--fw-motion-fast) var(--fw-motion-ease),
435
+ box-shadow var(--fw-motion-fast) var(--fw-motion-ease),
436
+ background var(--fw-motion-base) var(--fw-motion-ease),
437
+ color var(--fw-motion-base) var(--fw-motion-ease);
438
+ }
439
+ textarea.fw-input,
440
+ .fw-field textarea {
441
+ min-height: 96px;
442
+ resize: vertical;
443
+ }
444
+ .fw-input::placeholder,
445
+ .fw-field input::placeholder,
446
+ .fw-field textarea::placeholder {
447
+ color: var(--fw-text-soft);
448
+ opacity: 1;
449
+ }
450
+ .fw-input:focus,
451
+ .fw-field input:focus,
452
+ .fw-field select:focus,
453
+ .fw-field textarea:focus {
454
+ border-color: var(--fw-primary-hover);
455
+ box-shadow: var(--fw-focus-ring);
456
+ }
457
+ .fw-input.is-error,
458
+ .fw-input[aria-invalid=true],
459
+ .fw-field.is-error input,
460
+ .fw-field.is-error select,
461
+ .fw-field.is-error textarea,
462
+ .fw-field input.is-error,
463
+ .fw-field textarea.is-error {
464
+ border-color: var(--fw-danger);
465
+ }
466
+ .fw-input:disabled,
467
+ .fw-field input:disabled,
468
+ .fw-field select:disabled,
469
+ .fw-field textarea:disabled {
470
+ background: var(--fw-bg-dim);
471
+ color: var(--fw-text-soft);
472
+ border-color: var(--fw-bg-dim);
473
+ cursor: not-allowed;
474
+ }
475
+ .fw-field.is-disabled .fw-label,
476
+ .fw-field.is-disabled > label {
477
+ color: var(--fw-text-soft);
478
+ }
479
+
480
+ /* src/css/components/selection.css */
481
+ .fw-checkbox,
482
+ .fw-radio,
483
+ .fw-toggle {
484
+ position: relative;
485
+ display: inline-flex;
486
+ align-items: center;
487
+ gap: 10px;
488
+ cursor: pointer;
489
+ font-family: var(--fw-font-body);
490
+ font-size: 14px;
491
+ font-weight: 600;
492
+ color: var(--fw-text);
493
+ }
494
+ .fw-checkbox input,
495
+ .fw-radio input,
496
+ .fw-toggle input {
497
+ position: absolute;
498
+ opacity: 0;
499
+ width: 0;
500
+ height: 0;
501
+ margin: 0;
502
+ }
503
+ .fw-checkbox:has(input:disabled),
504
+ .fw-radio:has(input:disabled),
505
+ .fw-toggle:has(input:disabled) {
506
+ cursor: not-allowed;
507
+ }
508
+ .fw-checkbox input:disabled ~ span,
509
+ .fw-radio input:disabled ~ span,
510
+ .fw-toggle input:disabled ~ span {
511
+ color: var(--fw-text-soft);
512
+ }
513
+ .fw-option-group {
514
+ display: flex;
515
+ flex-direction: column;
516
+ gap: var(--fw-sp-3);
517
+ }
518
+ .fw-option-group-inline {
519
+ flex-direction: row;
520
+ flex-wrap: wrap;
521
+ gap: var(--fw-sp-5);
522
+ }
523
+ .fw-checkbox .fw-box {
524
+ width: 20px;
525
+ height: 20px;
526
+ border-radius: 6px;
527
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
528
+ background: var(--fw-surface);
529
+ display: flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ flex-shrink: 0;
533
+ transition: background var(--fw-motion-fast) var(--fw-motion-ease), border-color var(--fw-motion-fast) var(--fw-motion-ease);
534
+ }
535
+ .fw-checkbox .fw-box::after {
536
+ content: "";
537
+ width: 12px;
538
+ height: 12px;
539
+ opacity: 0;
540
+ background-color: var(--fw-on-primary);
541
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
542
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
543
+ transition: opacity 100ms var(--fw-motion-ease);
544
+ }
545
+ .fw-checkbox input:checked + .fw-box {
546
+ background: var(--fw-primary);
547
+ border-color: var(--fw-primary);
548
+ }
549
+ .fw-checkbox input:checked + .fw-box::after {
550
+ opacity: 1;
551
+ }
552
+ .fw-checkbox input:focus-visible + .fw-box {
553
+ box-shadow: var(--fw-focus-ring);
554
+ }
555
+ .fw-checkbox input:disabled + .fw-box {
556
+ background: var(--fw-bg-dim);
557
+ border-color: var(--fw-bg-dim);
558
+ }
559
+ .fw-radio .fw-box {
560
+ width: 20px;
561
+ height: 20px;
562
+ border-radius: 50%;
563
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
564
+ background: var(--fw-surface);
565
+ display: flex;
566
+ align-items: center;
567
+ justify-content: center;
568
+ flex-shrink: 0;
569
+ transition: border-color var(--fw-motion-fast) var(--fw-motion-ease);
570
+ }
571
+ .fw-radio .fw-box::after {
572
+ content: "";
573
+ width: 10px;
574
+ height: 10px;
575
+ border-radius: 50%;
576
+ background: transparent;
577
+ transition: background var(--fw-motion-fast) var(--fw-motion-ease);
578
+ }
579
+ .fw-radio input:checked + .fw-box {
580
+ border-color: var(--fw-primary);
581
+ }
582
+ .fw-radio input:checked + .fw-box::after {
583
+ background: var(--fw-primary);
584
+ }
585
+ .fw-radio input:focus-visible + .fw-box {
586
+ box-shadow: var(--fw-focus-ring);
587
+ }
588
+ .fw-radio input:disabled + .fw-box {
589
+ background: var(--fw-bg-dim);
590
+ border-color: var(--fw-bg-dim);
591
+ }
592
+ .fw-toggle .fw-track {
593
+ width: 42px;
594
+ height: 24px;
595
+ border-radius: var(--fw-r-full);
596
+ background: var(--fw-bg-dim);
597
+ position: relative;
598
+ flex-shrink: 0;
599
+ transition: background 160ms var(--fw-motion-ease);
600
+ }
601
+ .fw-toggle .fw-thumb {
602
+ position: absolute;
603
+ top: 2px;
604
+ left: 2px;
605
+ width: 20px;
606
+ height: 20px;
607
+ border-radius: 50%;
608
+ background: var(--fw-surface);
609
+ box-shadow: var(--fw-shadow-sm);
610
+ transition: transform 160ms var(--fw-motion-ease);
611
+ }
612
+ .fw-toggle input:checked + .fw-track {
613
+ background: var(--fw-primary);
614
+ }
615
+ .fw-toggle input:checked + .fw-track .fw-thumb {
616
+ transform: translateX(18px);
617
+ }
618
+ .fw-toggle input:focus-visible + .fw-track {
619
+ box-shadow: var(--fw-focus-ring);
620
+ }
621
+ .fw-toggle input:disabled + .fw-track {
622
+ opacity: 0.5;
623
+ }
624
+
625
+ /* src/css/components/combobox.css */
626
+ .fw-combobox {
627
+ position: relative;
628
+ }
629
+ .fw-combobox-list {
630
+ position: absolute;
631
+ top: calc(100% + 6px);
632
+ left: 0;
633
+ right: 0;
634
+ z-index: 30;
635
+ background: var(--fw-surface);
636
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
637
+ border-radius: var(--fw-r-md);
638
+ box-shadow: var(--fw-shadow-lg);
639
+ max-height: 220px;
640
+ overflow-y: auto;
641
+ padding: 6px;
642
+ margin: 0;
643
+ list-style: none;
644
+ opacity: 0;
645
+ transform: translateY(-4px);
646
+ pointer-events: none;
647
+ transition: opacity 140ms var(--fw-motion-ease), transform 140ms var(--fw-motion-ease);
648
+ }
649
+ .fw-combobox-list.is-open {
650
+ opacity: 1;
651
+ transform: translateY(0);
652
+ pointer-events: auto;
653
+ }
654
+ .fw-combobox-option {
655
+ padding: 10px 12px;
656
+ border-radius: var(--fw-r-sm);
657
+ font-family: var(--fw-font-body);
658
+ font-size: 14px;
659
+ cursor: pointer;
660
+ color: var(--fw-text);
661
+ }
662
+ .fw-combobox-option:hover,
663
+ .fw-combobox-option.is-active {
664
+ background: var(--fw-bg);
665
+ }
666
+ .fw-combobox-option b {
667
+ color: var(--fw-primary-hover);
668
+ font-weight: 700;
669
+ }
670
+ .fw-combobox-empty {
671
+ padding: 14px 12px;
672
+ font-size: 13px;
673
+ color: var(--fw-text-soft);
674
+ text-align: center;
675
+ }
676
+ @media (prefers-reduced-motion: reduce) {
677
+ .fw-combobox-list {
678
+ transform: none;
679
+ }
680
+ }
681
+
682
+ /* src/css/components/alert.css */
683
+ .fw-alert {
684
+ display: flex;
685
+ gap: var(--fw-sp-3);
686
+ padding: var(--fw-sp-4);
687
+ border-radius: var(--fw-r-md);
688
+ align-items: flex-start;
689
+ font-family: var(--fw-font-body);
690
+ color: var(--fw-text);
691
+ background: var(--fw-bg-dim);
692
+ }
693
+ .fw-alert-dot {
694
+ width: 20px;
695
+ height: 20px;
696
+ border-radius: 50%;
697
+ flex-shrink: 0;
698
+ margin-top: 2px;
699
+ background: var(--fw-text-soft);
700
+ }
701
+ .fw-alert-title {
702
+ font-weight: 700;
703
+ font-size: 14px;
704
+ }
705
+ .fw-alert-body {
706
+ font-size: 13px;
707
+ color: var(--fw-text-soft);
708
+ margin-top: 2px;
709
+ }
710
+ .fw-alert-success {
711
+ background: var(--fw-success-bg);
712
+ }
713
+ .fw-alert-success .fw-alert-dot {
714
+ background: var(--fw-success);
715
+ }
716
+ .fw-alert-error {
717
+ background: var(--fw-danger-bg);
718
+ }
719
+ .fw-alert-error .fw-alert-dot {
720
+ background: var(--fw-danger);
721
+ }
722
+ .fw-alert-pending {
723
+ background: var(--fw-warning-bg);
724
+ }
725
+ .fw-alert-pending .fw-alert-dot {
726
+ background: var(--fw-warning);
727
+ }
728
+ .fw-alert-info {
729
+ background: var(--fw-info-bg);
730
+ }
731
+ .fw-alert-info .fw-alert-dot {
732
+ background: var(--fw-info);
733
+ }
734
+ .fw-alert-with-action {
735
+ align-items: center;
736
+ justify-content: space-between;
737
+ flex-wrap: wrap;
738
+ }
739
+ .fw-alert-with-action .fw-alert-main {
740
+ display: flex;
741
+ align-items: center;
742
+ gap: var(--fw-sp-3);
743
+ }
744
+
745
+ /* src/css/components/progress.css */
746
+ .fw-progress-label {
747
+ display: flex;
748
+ justify-content: space-between;
749
+ align-items: baseline;
750
+ margin-bottom: 6px;
751
+ font-family: var(--fw-font-body);
752
+ font-size: 13px;
753
+ }
754
+ .fw-progress-name {
755
+ font-weight: 600;
756
+ color: var(--fw-text);
757
+ }
758
+ .fw-progress-pct {
759
+ font-family: var(--fw-font-mono);
760
+ color: var(--fw-text-soft);
761
+ }
762
+ .fw-progress {
763
+ position: relative;
764
+ height: 10px;
765
+ border-radius: var(--fw-r-full);
766
+ background: var(--fw-bg-dim);
767
+ overflow: hidden;
768
+ }
769
+ .fw-progress-sm {
770
+ height: 8px;
771
+ }
772
+ .fw-progress-fill {
773
+ height: 100%;
774
+ border-radius: var(--fw-r-full);
775
+ background: var(--fw-primary);
776
+ transition: width 400ms var(--fw-motion-ease);
777
+ }
778
+ .fw-progress.is-success .fw-progress-fill,
779
+ .fw-progress-fill.is-success {
780
+ background: var(--fw-success);
781
+ }
782
+ .fw-progress.is-indeterminate .fw-progress-fill {
783
+ position: absolute;
784
+ width: 40%;
785
+ left: -40%;
786
+ animation: fw-indeterminate-slide 1.4s ease-in-out infinite;
787
+ }
788
+ @keyframes fw-indeterminate-slide {
789
+ 0% {
790
+ left: -40%;
791
+ width: 40%;
792
+ }
793
+ 50% {
794
+ width: 60%;
795
+ }
796
+ 100% {
797
+ left: 100%;
798
+ width: 40%;
799
+ }
800
+ }
801
+ @media (prefers-reduced-motion: reduce) {
802
+ .fw-progress.is-indeterminate .fw-progress-fill {
803
+ position: static;
804
+ width: 100%;
805
+ animation: fw-pulse-opacity 1.2s ease-in-out infinite;
806
+ }
807
+ }
808
+
809
+ /* src/css/components/spinner.css */
810
+ .fw-spinner {
811
+ display: inline-block;
812
+ border-radius: 50%;
813
+ flex-shrink: 0;
814
+ width: 24px;
815
+ height: 24px;
816
+ border: 3px solid var(--fw-bg-dim);
817
+ border-top-color: currentColor;
818
+ animation: fw-spin 800ms linear infinite;
819
+ }
820
+ .fw-spinner-sm {
821
+ width: 16px;
822
+ height: 16px;
823
+ border-width: 2px;
824
+ }
825
+ .fw-spinner-md {
826
+ width: 24px;
827
+ height: 24px;
828
+ border-width: 3px;
829
+ }
830
+ .fw-spinner-lg {
831
+ width: 40px;
832
+ height: 40px;
833
+ border-width: 4px;
834
+ }
835
+ @keyframes fw-spin {
836
+ to {
837
+ transform: rotate(360deg);
838
+ }
839
+ }
840
+ @keyframes fw-pulse-opacity {
841
+ 0%, 100% {
842
+ opacity: 1;
843
+ }
844
+ 50% {
845
+ opacity: 0.35;
846
+ }
847
+ }
848
+ @media (prefers-reduced-motion: reduce) {
849
+ .fw-spinner {
850
+ animation: fw-pulse-opacity 1.2s ease-in-out infinite;
851
+ border-top-color: var(--fw-bg-dim);
852
+ }
853
+ }
854
+
855
+ /* src/css/components/nav.css */
856
+ .fw-nav {
857
+ position: relative;
858
+ background: var(--fw-secondary);
859
+ border-radius: var(--fw-r-lg);
860
+ padding: var(--fw-sp-4) var(--fw-sp-5);
861
+ display: flex;
862
+ align-items: center;
863
+ justify-content: space-between;
864
+ gap: var(--fw-sp-4);
865
+ box-shadow: var(--fw-shadow-md);
866
+ font-family: var(--fw-font-body);
867
+ color: var(--fw-on-secondary);
868
+ }
869
+ .fw-nav-sticky {
870
+ position: sticky;
871
+ top: var(--fw-sp-5);
872
+ z-index: 100;
873
+ }
874
+ .fw-nav-brand {
875
+ color: var(--fw-on-secondary);
876
+ font-family: var(--fw-font-display);
877
+ font-weight: 800;
878
+ font-size: 18px;
879
+ display: flex;
880
+ align-items: center;
881
+ gap: var(--fw-sp-2);
882
+ text-decoration: none;
883
+ }
884
+ .fw-nav-dot {
885
+ width: 10px;
886
+ height: 10px;
887
+ border-radius: 50%;
888
+ background: var(--fw-primary);
889
+ }
890
+ .fw-nav-hex {
891
+ width: 16px;
892
+ height: 16px;
893
+ background: var(--fw-primary);
894
+ clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
895
+ }
896
+ .fw-nav-links {
897
+ display: flex;
898
+ gap: var(--fw-sp-5);
899
+ align-items: center;
900
+ }
901
+ .fw-nav-links a {
902
+ color: var(--fw-on-secondary-soft);
903
+ font-size: 14px;
904
+ font-weight: 600;
905
+ text-decoration: none;
906
+ transition: color var(--fw-motion-fast) var(--fw-motion-ease);
907
+ }
908
+ .fw-nav-links a:hover {
909
+ color: var(--fw-on-secondary);
910
+ }
911
+ .fw-nav-links a.is-active {
912
+ color: var(--fw-on-secondary);
913
+ border-bottom: 2px solid var(--fw-primary);
914
+ padding-bottom: 3px;
915
+ }
916
+ .fw-nav-right {
917
+ display: flex;
918
+ align-items: center;
919
+ gap: var(--fw-sp-4);
920
+ }
921
+ .fw-nav-avatar {
922
+ width: 34px;
923
+ height: 34px;
924
+ border-radius: var(--fw-r-sm);
925
+ background: var(--fw-primary);
926
+ display: flex;
927
+ align-items: center;
928
+ justify-content: center;
929
+ font-weight: 800;
930
+ font-size: 13px;
931
+ color: var(--fw-on-primary);
932
+ font-family: var(--fw-font-display);
933
+ border: none;
934
+ padding: 0;
935
+ cursor: default;
936
+ }
937
+ .fw-nav-btn,
938
+ .fw-nav-toggle {
939
+ width: 38px;
940
+ height: 38px;
941
+ border-radius: var(--fw-r-sm);
942
+ background: var(--fw-on-secondary-fill);
943
+ border: var(--fw-border-w) solid var(--fw-on-secondary-line);
944
+ color: var(--fw-on-secondary);
945
+ cursor: pointer;
946
+ display: flex;
947
+ align-items: center;
948
+ justify-content: center;
949
+ padding: 0;
950
+ font-size: 15px;
951
+ transition: background var(--fw-motion-fast) var(--fw-motion-ease);
952
+ }
953
+ .fw-nav-btn:hover,
954
+ .fw-nav-toggle:hover {
955
+ background: var(--fw-on-secondary-line);
956
+ }
957
+ .fw-nav-btn:focus-visible,
958
+ .fw-nav-toggle:focus-visible {
959
+ outline: none;
960
+ box-shadow: var(--fw-focus-ring);
961
+ }
962
+ .fw-nav-toggle {
963
+ display: none;
964
+ flex-direction: column;
965
+ gap: 4px;
966
+ }
967
+ .fw-nav-toggle span {
968
+ width: 16px;
969
+ height: 2px;
970
+ background: var(--fw-on-secondary);
971
+ border-radius: 2px;
972
+ transition: transform var(--fw-motion-base) var(--fw-motion-ease), opacity var(--fw-motion-base) var(--fw-motion-ease);
973
+ }
974
+ .fw-nav-toggle[aria-expanded=true] span:nth-child(1) {
975
+ transform: translateY(6px) rotate(45deg);
976
+ }
977
+ .fw-nav-toggle[aria-expanded=true] span:nth-child(2) {
978
+ opacity: 0;
979
+ }
980
+ .fw-nav-toggle[aria-expanded=true] span:nth-child(3) {
981
+ transform: translateY(-6px) rotate(-45deg);
982
+ }
983
+ .fw-nav-dropdown {
984
+ position: absolute;
985
+ top: calc(100% + 8px);
986
+ left: 0;
987
+ right: 0;
988
+ z-index: 20;
989
+ background: var(--fw-surface);
990
+ border-radius: var(--fw-r-lg);
991
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
992
+ box-shadow: var(--fw-shadow-lg);
993
+ padding: var(--fw-sp-3);
994
+ display: flex;
995
+ flex-direction: column;
996
+ gap: 2px;
997
+ opacity: 0;
998
+ transform: translateY(-6px) scale(0.98);
999
+ pointer-events: none;
1000
+ transition: opacity 160ms var(--fw-motion-ease), transform 160ms var(--fw-motion-ease);
1001
+ }
1002
+ .fw-nav-dropdown.is-open {
1003
+ opacity: 1;
1004
+ transform: translateY(0) scale(1);
1005
+ pointer-events: auto;
1006
+ }
1007
+ .fw-nav-dropdown-menu {
1008
+ left: auto;
1009
+ min-width: 200px;
1010
+ }
1011
+ .fw-nav-dropdown a,
1012
+ .fw-nav-dropdown button {
1013
+ color: var(--fw-text);
1014
+ font-family: var(--fw-font-body);
1015
+ font-size: 15px;
1016
+ font-weight: 600;
1017
+ text-decoration: none;
1018
+ text-align: left;
1019
+ padding: 12px 14px;
1020
+ border-radius: var(--fw-r-sm);
1021
+ background: none;
1022
+ border: none;
1023
+ cursor: pointer;
1024
+ transition: background var(--fw-motion-fast) var(--fw-motion-ease);
1025
+ }
1026
+ .fw-nav-dropdown a:hover,
1027
+ .fw-nav-dropdown button:hover {
1028
+ background: var(--fw-bg);
1029
+ }
1030
+ .fw-nav-dropdown a.is-active {
1031
+ background: var(--fw-primary);
1032
+ color: var(--fw-on-primary);
1033
+ }
1034
+ @media (max-width: 600px) {
1035
+ .fw-nav-links {
1036
+ display: none;
1037
+ }
1038
+ .fw-nav-toggle {
1039
+ display: flex;
1040
+ }
1041
+ }
1042
+ @media (prefers-reduced-motion: reduce) {
1043
+ .fw-nav-dropdown {
1044
+ transform: none;
1045
+ }
1046
+ }
1047
+
1048
+ /* src/css/components/stat.css */
1049
+ .fw-stat-label {
1050
+ font-family: var(--fw-font-body);
1051
+ font-size: 13px;
1052
+ color: var(--fw-text-soft);
1053
+ font-weight: 600;
1054
+ }
1055
+ .fw-stat-value {
1056
+ font-family: var(--fw-font-display);
1057
+ font-size: 32px;
1058
+ font-weight: 800;
1059
+ line-height: 1.1;
1060
+ color: var(--fw-text);
1061
+ margin-top: 4px;
1062
+ }
1063
+ .fw-stat-value .fw-stat-unit {
1064
+ font-size: 18px;
1065
+ color: var(--fw-primary-hover);
1066
+ }
1067
+ .fw-stat-delta {
1068
+ font-family: var(--fw-font-mono);
1069
+ font-size: 12px;
1070
+ font-weight: 600;
1071
+ color: var(--fw-text-soft);
1072
+ margin-top: 4px;
1073
+ }
1074
+ .fw-stat-delta.is-up {
1075
+ color: var(--fw-success);
1076
+ }
1077
+ .fw-stat-delta.is-down {
1078
+ color: var(--fw-danger);
1079
+ }
1080
+
1081
+ /* src/css/components/empty.css */
1082
+ .fw-empty {
1083
+ text-align: center;
1084
+ padding: var(--fw-sp-7) var(--fw-sp-5);
1085
+ font-family: var(--fw-font-body);
1086
+ }
1087
+ .fw-empty-blob {
1088
+ width: 72px;
1089
+ height: 72px;
1090
+ margin: 0 auto var(--fw-sp-4);
1091
+ border-radius: 38% 62% 60% 40% / 48% 42% 58% 52%;
1092
+ background:
1093
+ linear-gradient(
1094
+ 135deg,
1095
+ var(--fw-primary),
1096
+ var(--fw-primary-soft));
1097
+ display: flex;
1098
+ align-items: center;
1099
+ justify-content: center;
1100
+ font-size: 28px;
1101
+ }
1102
+ .fw-empty-title {
1103
+ font-family: var(--fw-font-display);
1104
+ font-size: 17px;
1105
+ font-weight: 700;
1106
+ color: var(--fw-text);
1107
+ margin: 0 0 6px;
1108
+ }
1109
+ .fw-empty-body {
1110
+ font-size: 14px;
1111
+ color: var(--fw-text-soft);
1112
+ max-width: 36ch;
1113
+ margin: 0 auto var(--fw-sp-4);
1114
+ }
1115
+
1116
+ /* src/css/components/modal.css */
1117
+ .fw-modal-overlay {
1118
+ position: fixed;
1119
+ inset: 0;
1120
+ background: var(--fw-overlay);
1121
+ display: flex;
1122
+ align-items: center;
1123
+ justify-content: center;
1124
+ padding: var(--fw-sp-5);
1125
+ z-index: 100;
1126
+ opacity: 0;
1127
+ pointer-events: none;
1128
+ transition: opacity var(--fw-motion-base) var(--fw-motion-ease);
1129
+ }
1130
+ .fw-modal-overlay.is-open {
1131
+ opacity: 1;
1132
+ pointer-events: auto;
1133
+ }
1134
+ .fw-modal {
1135
+ background: var(--fw-surface);
1136
+ color: var(--fw-text);
1137
+ font-family: var(--fw-font-body);
1138
+ border-radius: var(--fw-r-xl);
1139
+ box-shadow: var(--fw-shadow-lg);
1140
+ width: 100%;
1141
+ max-width: 460px;
1142
+ max-height: 88vh;
1143
+ overflow-y: auto;
1144
+ padding: var(--fw-sp-6);
1145
+ transform: translateY(8px) scale(0.98);
1146
+ transition: transform var(--fw-motion-base) var(--fw-motion-ease);
1147
+ }
1148
+ .fw-modal-wide {
1149
+ max-width: 600px;
1150
+ }
1151
+ .fw-modal-overlay.is-open .fw-modal {
1152
+ transform: translateY(0) scale(1);
1153
+ }
1154
+ .fw-modal-head {
1155
+ display: flex;
1156
+ justify-content: space-between;
1157
+ align-items: flex-start;
1158
+ gap: var(--fw-sp-3);
1159
+ margin-bottom: var(--fw-sp-5);
1160
+ }
1161
+ .fw-modal-head h2,
1162
+ .fw-modal-title {
1163
+ font-family: var(--fw-font-display);
1164
+ font-size: 19px;
1165
+ font-weight: 800;
1166
+ color: var(--fw-text);
1167
+ margin: 0;
1168
+ }
1169
+ .fw-modal-sub {
1170
+ font-size: 13px;
1171
+ color: var(--fw-text-soft);
1172
+ margin: 2px 0 0;
1173
+ }
1174
+ .fw-modal-foot {
1175
+ display: flex;
1176
+ justify-content: flex-end;
1177
+ gap: var(--fw-sp-3);
1178
+ align-items: center;
1179
+ margin-top: var(--fw-sp-2);
1180
+ padding-top: var(--fw-sp-5);
1181
+ border-top: var(--fw-border-w) solid var(--fw-bg-dim);
1182
+ }
1183
+ @media (prefers-reduced-motion: reduce) {
1184
+ .fw-modal {
1185
+ transform: none;
1186
+ }
1187
+ }
1188
+
1189
+ /* src/css/components/drawer.css */
1190
+ .fw-drawer-overlay {
1191
+ position: fixed;
1192
+ inset: 0;
1193
+ background: var(--fw-overlay-soft);
1194
+ opacity: 0;
1195
+ pointer-events: none;
1196
+ transition: opacity var(--fw-motion-base) var(--fw-motion-ease);
1197
+ z-index: 90;
1198
+ }
1199
+ .fw-drawer-overlay.is-open {
1200
+ opacity: 1;
1201
+ pointer-events: auto;
1202
+ }
1203
+ .fw-drawer {
1204
+ position: fixed;
1205
+ top: 0;
1206
+ right: 0;
1207
+ height: 100%;
1208
+ width: 440px;
1209
+ max-width: 92vw;
1210
+ background: var(--fw-bg);
1211
+ color: var(--fw-text);
1212
+ font-family: var(--fw-font-body);
1213
+ box-shadow: var(--fw-shadow-lg);
1214
+ border-left: var(--fw-border-w) solid var(--fw-bg-dim);
1215
+ transform: translateX(100%);
1216
+ transition: transform 240ms var(--fw-motion-ease);
1217
+ z-index: 91;
1218
+ display: flex;
1219
+ flex-direction: column;
1220
+ }
1221
+ .fw-drawer.is-open {
1222
+ transform: translateX(0);
1223
+ }
1224
+ .fw-drawer-head {
1225
+ padding: var(--fw-sp-5);
1226
+ border-bottom: var(--fw-border-w) solid var(--fw-bg-dim);
1227
+ background: var(--fw-surface);
1228
+ display: flex;
1229
+ align-items: flex-start;
1230
+ gap: var(--fw-sp-3);
1231
+ flex-shrink: 0;
1232
+ }
1233
+ .fw-drawer-head-text {
1234
+ flex: 1;
1235
+ min-width: 0;
1236
+ }
1237
+ .fw-drawer-eyebrow {
1238
+ font-family: var(--fw-font-mono);
1239
+ font-size: 11px;
1240
+ font-weight: 600;
1241
+ letter-spacing: 0.06em;
1242
+ text-transform: uppercase;
1243
+ color: var(--fw-text-soft);
1244
+ margin-bottom: 4px;
1245
+ }
1246
+ .fw-drawer-title {
1247
+ font-family: var(--fw-font-display);
1248
+ font-size: 19px;
1249
+ font-weight: 800;
1250
+ color: var(--fw-text);
1251
+ margin: 0;
1252
+ }
1253
+ .fw-drawer-title-input {
1254
+ font-family: var(--fw-font-display);
1255
+ font-size: 19px;
1256
+ font-weight: 800;
1257
+ color: var(--fw-text);
1258
+ border: none;
1259
+ background: transparent;
1260
+ padding: 2px 0;
1261
+ width: 100%;
1262
+ outline: none;
1263
+ border-radius: 6px;
1264
+ }
1265
+ .fw-drawer-title-input:focus {
1266
+ background: var(--fw-bg);
1267
+ padding: 2px 6px;
1268
+ margin: 0 -6px;
1269
+ }
1270
+ .fw-drawer > form {
1271
+ flex: 1;
1272
+ min-height: 0;
1273
+ display: flex;
1274
+ flex-direction: column;
1275
+ }
1276
+ .fw-drawer-body {
1277
+ flex: 1;
1278
+ min-height: 0;
1279
+ overflow-y: auto;
1280
+ -webkit-overflow-scrolling: touch;
1281
+ padding: var(--fw-sp-5);
1282
+ display: flex;
1283
+ flex-direction: column;
1284
+ gap: var(--fw-sp-5);
1285
+ }
1286
+ .fw-drawer-foot {
1287
+ padding: var(--fw-sp-4) var(--fw-sp-5);
1288
+ display: flex;
1289
+ align-items: center;
1290
+ justify-content: space-between;
1291
+ gap: var(--fw-sp-3);
1292
+ flex-shrink: 0;
1293
+ border-top: var(--fw-border-w) solid var(--fw-bg-dim);
1294
+ background: var(--fw-surface);
1295
+ }
1296
+ @media (max-width: 560px) {
1297
+ .fw-drawer {
1298
+ width: 100vw;
1299
+ max-width: 100vw;
1300
+ }
1301
+ }
1302
+ @media (prefers-reduced-motion: reduce) {
1303
+ .fw-drawer {
1304
+ transition: opacity var(--fw-motion-base) var(--fw-motion-ease);
1305
+ transform: none;
1306
+ opacity: 0;
1307
+ pointer-events: none;
1308
+ }
1309
+ .fw-drawer.is-open {
1310
+ opacity: 1;
1311
+ pointer-events: auto;
1312
+ }
1313
+ }
1314
+
1315
+ /* src/css/components/toast.css */
1316
+ .fw-toast {
1317
+ position: fixed;
1318
+ bottom: var(--fw-sp-6);
1319
+ right: var(--fw-sp-6);
1320
+ z-index: 200;
1321
+ display: flex;
1322
+ align-items: center;
1323
+ gap: var(--fw-sp-3);
1324
+ max-width: min(360px, calc(100vw - 2 * var(--fw-sp-5)));
1325
+ background: var(--fw-success-bg);
1326
+ color: var(--fw-text);
1327
+ font-family: var(--fw-font-body);
1328
+ border-radius: var(--fw-r-md);
1329
+ padding: var(--fw-sp-3) var(--fw-sp-4);
1330
+ box-shadow: var(--fw-shadow-lg);
1331
+ font-size: 13px;
1332
+ font-weight: 600;
1333
+ transform: translateY(12px);
1334
+ opacity: 0;
1335
+ pointer-events: none;
1336
+ transition: transform var(--fw-motion-base) var(--fw-motion-ease), opacity var(--fw-motion-base) var(--fw-motion-ease);
1337
+ }
1338
+ .fw-toast.is-show {
1339
+ transform: translateY(0);
1340
+ opacity: 1;
1341
+ pointer-events: auto;
1342
+ }
1343
+ .fw-toast-dot {
1344
+ width: 8px;
1345
+ height: 8px;
1346
+ border-radius: 50%;
1347
+ background: var(--fw-success);
1348
+ flex-shrink: 0;
1349
+ }
1350
+ .fw-toast-error {
1351
+ background: var(--fw-danger-bg);
1352
+ }
1353
+ .fw-toast-error .fw-toast-dot {
1354
+ background: var(--fw-danger);
1355
+ }
1356
+ .fw-toast-info {
1357
+ background: var(--fw-info-bg);
1358
+ }
1359
+ .fw-toast-info .fw-toast-dot {
1360
+ background: var(--fw-info);
1361
+ }
1362
+ .fw-toast-pending {
1363
+ background: var(--fw-warning-bg);
1364
+ }
1365
+ .fw-toast-pending .fw-toast-dot {
1366
+ background: var(--fw-warning);
1367
+ }
1368
+ @media (prefers-reduced-motion: reduce) {
1369
+ .fw-toast {
1370
+ transform: none;
1371
+ }
1372
+ }
1373
+
1374
+ /* src/css/components/list-row.css */
1375
+ .fw-list-row {
1376
+ display: block;
1377
+ background: var(--fw-surface);
1378
+ border-radius: var(--fw-r-lg);
1379
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
1380
+ box-shadow: var(--fw-shadow-sm);
1381
+ padding: var(--fw-sp-4) var(--fw-sp-5);
1382
+ color: inherit;
1383
+ font-family: var(--fw-font-body);
1384
+ text-decoration: none;
1385
+ transition: transform var(--fw-motion-fast) var(--fw-motion-ease), box-shadow var(--fw-motion-fast) var(--fw-motion-ease);
1386
+ }
1387
+ .fw-list-row:hover {
1388
+ transform: translateY(-1px);
1389
+ box-shadow: var(--fw-shadow-md);
1390
+ text-decoration: none;
1391
+ }
1392
+ .fw-list-row:focus-visible {
1393
+ outline: none;
1394
+ box-shadow: var(--fw-focus-ring);
1395
+ }
1396
+ .fw-list-row.is-locked {
1397
+ opacity: 0.6;
1398
+ }
1399
+ .fw-list-row.is-locked:hover {
1400
+ transform: none;
1401
+ box-shadow: var(--fw-shadow-sm);
1402
+ }
1403
+ .fw-list-row + .fw-list-row {
1404
+ margin-top: var(--fw-sp-3);
1405
+ }
1406
+ .fw-list-row-main {
1407
+ display: flex;
1408
+ flex-wrap: wrap;
1409
+ align-items: center;
1410
+ gap: var(--fw-sp-2) var(--fw-sp-4);
1411
+ }
1412
+ .fw-list-row-title {
1413
+ font-family: var(--fw-font-display);
1414
+ font-weight: 700;
1415
+ font-size: 16px;
1416
+ color: var(--fw-text);
1417
+ }
1418
+ .fw-list-row-meta {
1419
+ font-size: 13px;
1420
+ color: var(--fw-text-soft);
1421
+ }
1422
+ .fw-sub-list {
1423
+ margin: var(--fw-sp-2) 0 0 var(--fw-sp-5);
1424
+ padding-left: var(--fw-sp-4);
1425
+ border-left: var(--fw-border-w) solid var(--fw-bg-dim);
1426
+ }
1427
+ .fw-sub-list-row {
1428
+ display: flex;
1429
+ flex-wrap: wrap;
1430
+ align-items: center;
1431
+ gap: var(--fw-sp-2) var(--fw-sp-3);
1432
+ padding: var(--fw-sp-2) 0;
1433
+ }
1434
+ .fw-sub-list-row + .fw-sub-list-row {
1435
+ border-top: 1px solid var(--fw-bg-dim);
1436
+ }
1437
+ .fw-sub-list-title {
1438
+ font-size: 13.5px;
1439
+ font-weight: 600;
1440
+ color: var(--fw-text);
1441
+ }
1442
+
1443
+ /* src/css/components/disclosure.css */
1444
+ .fw-disclosure > summary {
1445
+ cursor: pointer;
1446
+ color: var(--fw-secondary);
1447
+ font-family: var(--fw-font-body);
1448
+ font-weight: 600;
1449
+ font-size: 13px;
1450
+ list-style: none;
1451
+ display: flex;
1452
+ align-items: center;
1453
+ gap: 6px;
1454
+ }
1455
+ .fw-disclosure > summary::-webkit-details-marker {
1456
+ display: none;
1457
+ }
1458
+ .fw-disclosure > summary:hover {
1459
+ text-decoration: underline;
1460
+ }
1461
+ .fw-disclosure > summary:focus-visible {
1462
+ outline: none;
1463
+ border-radius: 4px;
1464
+ box-shadow: var(--fw-focus-ring);
1465
+ }
1466
+ .fw-disclosure-chevron {
1467
+ width: 12px;
1468
+ height: 12px;
1469
+ flex-shrink: 0;
1470
+ transition: transform 150ms var(--fw-motion-ease);
1471
+ }
1472
+ .fw-disclosure[open] > summary .fw-disclosure-chevron {
1473
+ transform: rotate(180deg);
1474
+ }
1475
+ .fw-disclosure-count {
1476
+ font-family: var(--fw-font-mono);
1477
+ font-size: 10.5px;
1478
+ font-weight: 700;
1479
+ color: var(--fw-secondary);
1480
+ background: var(--fw-surface);
1481
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
1482
+ border-radius: var(--fw-r-full);
1483
+ padding: 1px 7px;
1484
+ }
1485
+ .fw-disclosure-body {
1486
+ margin-top: var(--fw-sp-3);
1487
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
1488
+ border-radius: var(--fw-r-md);
1489
+ padding: var(--fw-sp-4);
1490
+ background: var(--fw-bg);
1491
+ display: flex;
1492
+ flex-direction: column;
1493
+ gap: var(--fw-sp-3);
1494
+ }
1495
+
1496
+ /* src/css/components/pagination.css */
1497
+ .fw-pagination {
1498
+ display: flex;
1499
+ align-items: center;
1500
+ justify-content: space-between;
1501
+ flex-wrap: wrap;
1502
+ gap: var(--fw-sp-3);
1503
+ font-family: var(--fw-font-body);
1504
+ }
1505
+ .fw-pag-info,
1506
+ .fw-pag-label {
1507
+ font-family: var(--fw-font-mono);
1508
+ font-size: 12px;
1509
+ color: var(--fw-text-soft);
1510
+ }
1511
+ .fw-pag-controls {
1512
+ display: flex;
1513
+ align-items: center;
1514
+ gap: var(--fw-sp-3);
1515
+ }
1516
+ .fw-btn-page {
1517
+ display: inline-flex;
1518
+ align-items: center;
1519
+ height: 34px;
1520
+ padding: 0 14px;
1521
+ border-radius: var(--fw-r-sm);
1522
+ border: var(--fw-border-w) solid var(--fw-bg-dim);
1523
+ background: var(--fw-surface);
1524
+ color: var(--fw-text);
1525
+ font-family: var(--fw-font-body);
1526
+ font-size: 13px;
1527
+ font-weight: 600;
1528
+ text-decoration: none;
1529
+ cursor: pointer;
1530
+ transition: border-color var(--fw-motion-fast) var(--fw-motion-ease);
1531
+ }
1532
+ .fw-btn-page:hover {
1533
+ border-color: var(--fw-text-soft);
1534
+ text-decoration: none;
1535
+ }
1536
+ .fw-btn-page:focus-visible {
1537
+ outline: none;
1538
+ box-shadow: var(--fw-focus-ring);
1539
+ }
1540
+ .fw-btn-page.is-disabled,
1541
+ .fw-btn-page[aria-disabled=true],
1542
+ .fw-btn-page:disabled {
1543
+ opacity: 0.35;
1544
+ cursor: not-allowed;
1545
+ pointer-events: none;
1546
+ }
1547
+
1548
+ /* src/css/index.css */