@cahyo-dimas/freeday 1.7.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +447 -0
  2. package/LICENSE +21 -0
  3. package/README.md +205 -0
  4. package/adapters/blazor/freeday-blazor.js +79 -0
  5. package/adapters/react/components/FdyAutocomplete.tsx +159 -0
  6. package/adapters/react/components/FdyCascade.tsx +230 -0
  7. package/adapters/react/components/FdyCfl.tsx +362 -0
  8. package/adapters/react/components/FdyChart.tsx +69 -0
  9. package/adapters/react/components/FdyCombo.tsx +166 -0
  10. package/adapters/react/components/FdyDateRange.tsx +66 -0
  11. package/adapters/react/components/FdyDatepicker.tsx +354 -0
  12. package/adapters/react/index.d.ts +37 -0
  13. package/adapters/react/index.js +9 -0
  14. package/adapters/react/tsconfig.json +14 -0
  15. package/adapters/react/useFreeday.js +44 -0
  16. package/adapters/react/usePopover.ts +64 -0
  17. package/adapters/vue/components/FdyAutocomplete.vue +174 -0
  18. package/adapters/vue/components/FdyCascade.vue +241 -0
  19. package/adapters/vue/components/FdyCfl.vue +354 -0
  20. package/adapters/vue/components/FdyChart.vue +89 -0
  21. package/adapters/vue/components/FdyCombo.vue +232 -0
  22. package/adapters/vue/components/FdyDateRange.vue +78 -0
  23. package/adapters/vue/components/FdyDatepicker.vue +333 -0
  24. package/adapters/vue/index.d.ts +44 -0
  25. package/adapters/vue/index.js +8 -0
  26. package/adapters/vue/useFreeday.js +44 -0
  27. package/adapters/vue/usePopover.ts +78 -0
  28. package/dist/freeday-autocomplete.js +135 -0
  29. package/dist/freeday-breakpoint.js +51 -0
  30. package/dist/freeday-carousel.js +111 -0
  31. package/dist/freeday-cascade.js +256 -0
  32. package/dist/freeday-cfl.js +213 -0
  33. package/dist/freeday-chart.js +403 -0
  34. package/dist/freeday-chip.js +83 -0
  35. package/dist/freeday-datepicker.js +321 -0
  36. package/dist/freeday-datetime.js +59 -0
  37. package/dist/freeday-drawer.js +43 -0
  38. package/dist/freeday-form.js +181 -0
  39. package/dist/freeday-mask.js +114 -0
  40. package/dist/freeday-menu.js +93 -0
  41. package/dist/freeday-popover.js +69 -0
  42. package/dist/freeday-rating.js +50 -0
  43. package/dist/freeday-select.js +194 -0
  44. package/dist/freeday-slider.js +34 -0
  45. package/dist/freeday-stepper.js +90 -0
  46. package/dist/freeday-table.js +475 -0
  47. package/dist/freeday-tabs.js +68 -0
  48. package/dist/freeday-timepicker.js +180 -0
  49. package/dist/freeday-toast.js +84 -0
  50. package/dist/freeday-tree.js +94 -0
  51. package/dist/freeday-upload.js +206 -0
  52. package/dist/freeday.bundle.css +1352 -0
  53. package/dist/freeday.css +1007 -0
  54. package/dist/freeday.js +3632 -0
  55. package/dist/freeday.tokens.css +343 -0
  56. package/package.json +72 -0
  57. package/src/base.css +20 -0
  58. package/src/components/.gitkeep +0 -0
  59. package/src/components/accordion.css +13 -0
  60. package/src/components/alert.css +18 -0
  61. package/src/components/app-shell.css +88 -0
  62. package/src/components/appbar.css +15 -0
  63. package/src/components/autocomplete.css +12 -0
  64. package/src/components/avatar.css +8 -0
  65. package/src/components/badge.css +27 -0
  66. package/src/components/breadcrumb.css +9 -0
  67. package/src/components/breakpoints.css +15 -0
  68. package/src/components/button.css +58 -0
  69. package/src/components/card.css +9 -0
  70. package/src/components/carousel.css +17 -0
  71. package/src/components/cascade.css +36 -0
  72. package/src/components/cfl.css +28 -0
  73. package/src/components/chart.css +55 -0
  74. package/src/components/chip.css +18 -0
  75. package/src/components/combo.css +27 -0
  76. package/src/components/datepicker.css +44 -0
  77. package/src/components/datetimepicker.css +8 -0
  78. package/src/components/description-list.css +6 -0
  79. package/src/components/divider.css +3 -0
  80. package/src/components/drawer.css +25 -0
  81. package/src/components/file-upload.css +34 -0
  82. package/src/components/filterbar.css +25 -0
  83. package/src/components/form-grid.css +8 -0
  84. package/src/components/input-group.css +22 -0
  85. package/src/components/input.css +13 -0
  86. package/src/components/kbd.css +2 -0
  87. package/src/components/menu.css +28 -0
  88. package/src/components/modal.css +22 -0
  89. package/src/components/pagination.css +8 -0
  90. package/src/components/progress.css +7 -0
  91. package/src/components/rating.css +10 -0
  92. package/src/components/selection.css +25 -0
  93. package/src/components/skeleton.css +7 -0
  94. package/src/components/slider.css +12 -0
  95. package/src/components/spinner.css +6 -0
  96. package/src/components/states.css +8 -0
  97. package/src/components/stepper.css +21 -0
  98. package/src/components/table.css +55 -0
  99. package/src/components/tabs.css +10 -0
  100. package/src/components/timeline.css +12 -0
  101. package/src/components/timepicker.css +22 -0
  102. package/src/components/toast.css +17 -0
  103. package/src/components/tooltip.css +6 -0
  104. package/src/components/tree.css +21 -0
  105. package/src/freeday-autocomplete.js +135 -0
  106. package/src/freeday-breakpoint.js +51 -0
  107. package/src/freeday-carousel.js +111 -0
  108. package/src/freeday-cascade.js +256 -0
  109. package/src/freeday-cfl.js +213 -0
  110. package/src/freeday-chart.js +403 -0
  111. package/src/freeday-chip.js +83 -0
  112. package/src/freeday-datepicker.js +321 -0
  113. package/src/freeday-datetime.js +59 -0
  114. package/src/freeday-drawer.js +43 -0
  115. package/src/freeday-form.js +181 -0
  116. package/src/freeday-mask.js +114 -0
  117. package/src/freeday-menu.js +93 -0
  118. package/src/freeday-popover.js +69 -0
  119. package/src/freeday-rating.js +50 -0
  120. package/src/freeday-select.js +194 -0
  121. package/src/freeday-slider.js +34 -0
  122. package/src/freeday-stepper.js +90 -0
  123. package/src/freeday-table.js +475 -0
  124. package/src/freeday-tabs.js +68 -0
  125. package/src/freeday-timepicker.js +180 -0
  126. package/src/freeday-toast.js +84 -0
  127. package/src/freeday-tree.js +94 -0
  128. package/src/freeday-upload.js +206 -0
  129. package/tokens/breakpoints.mjs +4 -0
  130. package/tokens/tokens.json +123 -0
@@ -0,0 +1,343 @@
1
+ /* Freeday tokens — GENERATED by tokens/build.mjs. Do not edit by hand. */
2
+ :root {
3
+ --azure-50: #eff4ff;
4
+ --azure-100: #dbe6fe;
5
+ --azure-200: #bdd2fd;
6
+ --azure-300: #90b3fb;
7
+ --azure-400: #5c8bf6;
8
+ --azure-500: #3467ec;
9
+ --azure-600: #2050d8;
10
+ --azure-700: #1c40b0;
11
+ --azure-800: #1c398c;
12
+ --azure-900: #1c336e;
13
+ --azure-950: #131e42;
14
+ --slate-0: #ffffff;
15
+ --slate-50: #f7f8fa;
16
+ --slate-100: #eef0f4;
17
+ --slate-200: #e0e3ea;
18
+ --slate-300: #cbd0da;
19
+ --slate-400: #99a1b3;
20
+ --slate-500: #6b7488;
21
+ --slate-600: #4d5568;
22
+ --slate-700: #3a4152;
23
+ --slate-800: #262b38;
24
+ --slate-900: #171b26;
25
+ --slate-950: #0e111a;
26
+ --sky-50: #eff6fd;
27
+ --sky-100: #d6e9fb;
28
+ --sky-200: #b0d4f6;
29
+ --sky-300: #7bbdef;
30
+ --sky-400: #47a1e6;
31
+ --sky-500: #1a86dc;
32
+ --sky-600: #0078d4;
33
+ --sky-700: #0061ac;
34
+ --sky-800: #004d88;
35
+ --sky-900: #003a67;
36
+ --red-100: #fee2e2;
37
+ --red-300: #fca5a5;
38
+ --red-400: #f87171;
39
+ --red-500: #ef4444;
40
+ --red-600: #dc2626;
41
+ --red-700: #b91c1c;
42
+ --amber-100: #fef3c7;
43
+ --amber-400: #fbbf24;
44
+ --amber-500: #f59e0b;
45
+ --amber-600: #d97706;
46
+ --amber-700: #b45309;
47
+ --amber-800: #92400e;
48
+ --green-100: #dcfce7;
49
+ --green-400: #4ade80;
50
+ --green-500: #22c55e;
51
+ --green-600: #16a34a;
52
+ --green-700: #15803d;
53
+ --green-800: #166534;
54
+ --blue-100: #dbeafe;
55
+ --blue-300: #93c5fd;
56
+ --blue-400: #60a5fa;
57
+ --blue-500: #3b82f6;
58
+ --blue-600: #2563eb;
59
+ --blue-700: #1d4ed8;
60
+ --font-display: 'Sora', ui-sans-serif, system-ui, sans-serif;
61
+ --font-body: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
62
+ --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
63
+ --text-xs: 0.75rem;
64
+ --text-sm: 0.875rem;
65
+ --text-base: 1rem;
66
+ --text-lg: 1.125rem;
67
+ --text-xl: 1.25rem;
68
+ --text-2xl: 1.5625rem;
69
+ --text-3xl: 1.9375rem;
70
+ --text-4xl: 2.4375rem;
71
+ --text-5xl: 3.0625rem;
72
+ --leading-tight: 1.2;
73
+ --leading-snug: 1.35;
74
+ --leading-normal: 1.55;
75
+ --leading-loose: 1.75;
76
+ --tracking-tighter: -0.03em;
77
+ --tracking-tight: -0.02em;
78
+ --tracking-normal: 0;
79
+ --tracking-wide: 0.06em;
80
+ --weight-regular: 400;
81
+ --weight-medium: 500;
82
+ --weight-semibold: 600;
83
+ --weight-bold: 700;
84
+ --space-0: 0;
85
+ --space-1: 0.25rem;
86
+ --space-2: 0.5rem;
87
+ --space-3: 0.75rem;
88
+ --space-4: 1rem;
89
+ --space-5: 1.25rem;
90
+ --space-6: 1.5rem;
91
+ --space-8: 2rem;
92
+ --space-10: 2.5rem;
93
+ --space-12: 3rem;
94
+ --space-16: 4rem;
95
+ --space-20: 5rem;
96
+ --space-24: 6rem;
97
+ --radius-xs: 3px;
98
+ --radius-sm: 4px;
99
+ --radius-md: 6px;
100
+ --radius-lg: 10px;
101
+ --radius-xl: 14px;
102
+ --radius-full: 999px;
103
+ --shadow-1: 0 1px 2px rgba(16,14,30,.06);
104
+ --shadow-2: 0 2px 6px rgba(16,14,30,.07),0 1px 2px rgba(16,14,30,.05);
105
+ --shadow-3: 0 4px 16px -2px rgba(16,14,30,.14),0 1px 3px rgba(16,14,30,.10);
106
+ --shadow-4: 0 24px 48px -12px rgba(16,14,30,.26),0 2px 8px rgba(16,14,30,.10);
107
+ --shadow-lift: 0 1px 2px rgba(16,14,30,.05),0 16px 34px -14px rgba(16,14,30,.24);
108
+ --shadow-lift-hover: 0 2px 4px rgba(16,14,30,.06),0 30px 50px -16px rgba(16,14,30,.33);
109
+ --dur-fast: 120ms;
110
+ --dur-base: 180ms;
111
+ --dur-slow: 280ms;
112
+ --ease-standard: cubic-bezier(.2,0,0,1);
113
+ --ease-spring: cubic-bezier(.2,.8,.2,1);
114
+ --control-h: 2.5rem;
115
+ --control-box: 1.15rem;
116
+ --control-switch-w: 2.4rem;
117
+ --control-switch-h: 1.35rem;
118
+ --bw: 1px;
119
+ --color-primary: var(--azure-600);
120
+ --color-primary-hover: var(--azure-700);
121
+ --color-primary-active: var(--azure-800);
122
+ --color-on-primary: var(--slate-0);
123
+ --color-primary-soft: var(--azure-50);
124
+ --color-primary-border: var(--azure-100);
125
+ --color-accent: var(--sky-600);
126
+ --color-accent-hover: var(--sky-700);
127
+ --color-on-accent: var(--slate-0);
128
+ --color-on-danger: var(--slate-0);
129
+ --color-danger-btn: var(--red-600);
130
+ --color-surface: var(--slate-0);
131
+ --color-surface-2: var(--slate-50);
132
+ --color-surface-3: var(--slate-100);
133
+ --color-text: var(--slate-900);
134
+ --color-text-muted: var(--slate-600);
135
+ --color-text-subtle: var(--slate-500);
136
+ --color-on-brand: var(--slate-0);
137
+ --color-border: var(--slate-200);
138
+ --color-border-strong: var(--slate-300);
139
+ --color-border-muted: var(--slate-100);
140
+ --color-control-border: var(--slate-500);
141
+ --color-switch-thumb: var(--slate-0);
142
+ --color-shadow-inset: rgba(16,14,30,.06);
143
+ --color-inverse-surface: var(--slate-900);
144
+ --color-inverse-text: var(--slate-0);
145
+ --color-success: var(--green-600);
146
+ --color-success-soft: var(--green-100);
147
+ --color-warning: #c2740a;
148
+ --color-warning-soft: var(--amber-100);
149
+ --color-danger: var(--red-600);
150
+ --color-danger-soft: var(--red-100);
151
+ --color-info: var(--blue-600);
152
+ --color-info-soft: var(--blue-100);
153
+ --color-primary-strong: var(--azure-700);
154
+ --color-success-strong: var(--green-800);
155
+ --color-warning-strong: var(--amber-800);
156
+ --color-danger-strong: var(--red-700);
157
+ --color-info-strong: var(--blue-700);
158
+ --chart-1: #2a78d6;
159
+ --chart-2: #eb6834;
160
+ --chart-3: #1baf7a;
161
+ --chart-4: #eda100;
162
+ --chart-5: #e87ba4;
163
+ --chart-6: #008300;
164
+ --chart-7: #4a3aa7;
165
+ --chart-8: #e34948;
166
+ --chart-grid: var(--slate-200);
167
+ --chart-tick: var(--slate-400);
168
+ --focus-ring: var(--azure-600);
169
+ --focus-ring-width: 2px;
170
+ }
171
+ @media (prefers-color-scheme: dark) {
172
+ :root:not([data-theme="light"]) {
173
+ --shadow-1: 0 1px 2px rgba(0,0,0,.4);
174
+ --shadow-2: 0 2px 6px rgba(0,0,0,.45);
175
+ --shadow-3: 0 6px 20px -2px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.5);
176
+ --shadow-4: 0 28px 56px -12px rgba(0,0,0,.72),0 2px 8px rgba(0,0,0,.5);
177
+ --shadow-lift: 0 1px 2px rgba(0,0,0,.5),0 18px 38px -14px rgba(0,0,0,.72);
178
+ --shadow-lift-hover: 0 3px 6px rgba(0,0,0,.55),0 32px 56px -16px rgba(0,0,0,.82);
179
+ --color-primary: var(--azure-500);
180
+ --color-primary-hover: var(--azure-400);
181
+ --color-primary-active: var(--azure-300);
182
+ --color-on-primary: var(--slate-0);
183
+ --color-primary-soft: rgba(32,80,216,.20);
184
+ --color-primary-border: rgba(92,139,246,.28);
185
+ --color-accent: var(--sky-400);
186
+ --color-accent-hover: var(--sky-300);
187
+ --color-on-accent: #06233f;
188
+ --color-on-danger: var(--slate-0);
189
+ --color-danger-btn: var(--red-600);
190
+ --color-surface: var(--slate-950);
191
+ --color-surface-2: var(--slate-900);
192
+ --color-surface-3: var(--slate-800);
193
+ --color-text: var(--slate-100);
194
+ --color-text-muted: var(--slate-400);
195
+ --color-text-subtle: var(--slate-500);
196
+ --color-on-brand: var(--slate-0);
197
+ --color-border: var(--slate-800);
198
+ --color-border-strong: var(--slate-700);
199
+ --color-border-muted: #1c2130;
200
+ --color-control-border: var(--slate-500);
201
+ --color-inverse-surface: var(--slate-100);
202
+ --color-inverse-text: var(--slate-900);
203
+ --color-success: var(--green-500);
204
+ --color-success-soft: rgba(34,197,94,.18);
205
+ --color-warning: var(--amber-500);
206
+ --color-warning-soft: rgba(234,179,8,.18);
207
+ --color-danger: var(--red-400);
208
+ --color-danger-soft: rgba(248,113,113,.18);
209
+ --color-info: var(--blue-400);
210
+ --color-info-soft: rgba(96,165,250,.18);
211
+ --color-primary-strong: var(--azure-300);
212
+ --color-success-strong: var(--green-400);
213
+ --color-warning-strong: var(--amber-400);
214
+ --color-danger-strong: var(--red-300);
215
+ --color-info-strong: var(--blue-300);
216
+ --chart-1: #3987e5;
217
+ --chart-2: #d95926;
218
+ --chart-3: #199e70;
219
+ --chart-4: #c98500;
220
+ --chart-5: #d55181;
221
+ --chart-6: #008300;
222
+ --chart-7: #9085e9;
223
+ --chart-8: #e66767;
224
+ --chart-grid: var(--slate-800);
225
+ --chart-tick: var(--slate-600);
226
+ --focus-ring: var(--azure-400);
227
+ }
228
+ }
229
+ :root[data-theme="dark"] {
230
+ --shadow-1: 0 1px 2px rgba(0,0,0,.4);
231
+ --shadow-2: 0 2px 6px rgba(0,0,0,.45);
232
+ --shadow-3: 0 6px 20px -2px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.5);
233
+ --shadow-4: 0 28px 56px -12px rgba(0,0,0,.72),0 2px 8px rgba(0,0,0,.5);
234
+ --shadow-lift: 0 1px 2px rgba(0,0,0,.5),0 18px 38px -14px rgba(0,0,0,.72);
235
+ --shadow-lift-hover: 0 3px 6px rgba(0,0,0,.55),0 32px 56px -16px rgba(0,0,0,.82);
236
+ --color-primary: var(--azure-500);
237
+ --color-primary-hover: var(--azure-400);
238
+ --color-primary-active: var(--azure-300);
239
+ --color-on-primary: var(--slate-0);
240
+ --color-primary-soft: rgba(32,80,216,.20);
241
+ --color-primary-border: rgba(92,139,246,.28);
242
+ --color-accent: var(--sky-400);
243
+ --color-accent-hover: var(--sky-300);
244
+ --color-on-accent: #06233f;
245
+ --color-on-danger: var(--slate-0);
246
+ --color-danger-btn: var(--red-600);
247
+ --color-surface: var(--slate-950);
248
+ --color-surface-2: var(--slate-900);
249
+ --color-surface-3: var(--slate-800);
250
+ --color-text: var(--slate-100);
251
+ --color-text-muted: var(--slate-400);
252
+ --color-text-subtle: var(--slate-500);
253
+ --color-on-brand: var(--slate-0);
254
+ --color-border: var(--slate-800);
255
+ --color-border-strong: var(--slate-700);
256
+ --color-border-muted: #1c2130;
257
+ --color-control-border: var(--slate-500);
258
+ --color-inverse-surface: var(--slate-100);
259
+ --color-inverse-text: var(--slate-900);
260
+ --color-success: var(--green-500);
261
+ --color-success-soft: rgba(34,197,94,.18);
262
+ --color-warning: var(--amber-500);
263
+ --color-warning-soft: rgba(234,179,8,.18);
264
+ --color-danger: var(--red-400);
265
+ --color-danger-soft: rgba(248,113,113,.18);
266
+ --color-info: var(--blue-400);
267
+ --color-info-soft: rgba(96,165,250,.18);
268
+ --color-primary-strong: var(--azure-300);
269
+ --color-success-strong: var(--green-400);
270
+ --color-warning-strong: var(--amber-400);
271
+ --color-danger-strong: var(--red-300);
272
+ --color-info-strong: var(--blue-300);
273
+ --chart-1: #3987e5;
274
+ --chart-2: #d95926;
275
+ --chart-3: #199e70;
276
+ --chart-4: #c98500;
277
+ --chart-5: #d55181;
278
+ --chart-6: #008300;
279
+ --chart-7: #9085e9;
280
+ --chart-8: #e66767;
281
+ --chart-grid: var(--slate-800);
282
+ --chart-tick: var(--slate-600);
283
+ --focus-ring: var(--azure-400);
284
+ }
285
+ :root[data-theme="light"] {
286
+ --shadow-1: 0 1px 2px rgba(16,14,30,.06);
287
+ --shadow-2: 0 2px 6px rgba(16,14,30,.07),0 1px 2px rgba(16,14,30,.05);
288
+ --shadow-3: 0 4px 16px -2px rgba(16,14,30,.14),0 1px 3px rgba(16,14,30,.10);
289
+ --shadow-4: 0 24px 48px -12px rgba(16,14,30,.26),0 2px 8px rgba(16,14,30,.10);
290
+ --shadow-lift: 0 1px 2px rgba(16,14,30,.05),0 16px 34px -14px rgba(16,14,30,.24);
291
+ --shadow-lift-hover: 0 2px 4px rgba(16,14,30,.06),0 30px 50px -16px rgba(16,14,30,.33);
292
+ --color-primary: var(--azure-600);
293
+ --color-primary-hover: var(--azure-700);
294
+ --color-primary-active: var(--azure-800);
295
+ --color-on-primary: var(--slate-0);
296
+ --color-primary-soft: var(--azure-50);
297
+ --color-primary-border: var(--azure-100);
298
+ --color-accent: var(--sky-600);
299
+ --color-accent-hover: var(--sky-700);
300
+ --color-on-accent: var(--slate-0);
301
+ --color-on-danger: var(--slate-0);
302
+ --color-danger-btn: var(--red-600);
303
+ --color-surface: var(--slate-0);
304
+ --color-surface-2: var(--slate-50);
305
+ --color-surface-3: var(--slate-100);
306
+ --color-text: var(--slate-900);
307
+ --color-text-muted: var(--slate-600);
308
+ --color-text-subtle: var(--slate-500);
309
+ --color-on-brand: var(--slate-0);
310
+ --color-border: var(--slate-200);
311
+ --color-border-strong: var(--slate-300);
312
+ --color-border-muted: var(--slate-100);
313
+ --color-control-border: var(--slate-500);
314
+ --color-inverse-surface: var(--slate-900);
315
+ --color-inverse-text: var(--slate-0);
316
+ --color-success: var(--green-600);
317
+ --color-success-soft: var(--green-100);
318
+ --color-warning: #c2740a;
319
+ --color-warning-soft: var(--amber-100);
320
+ --color-danger: var(--red-600);
321
+ --color-danger-soft: var(--red-100);
322
+ --color-info: var(--blue-600);
323
+ --color-info-soft: var(--blue-100);
324
+ --color-primary-strong: var(--azure-700);
325
+ --color-success-strong: var(--green-800);
326
+ --color-warning-strong: var(--amber-800);
327
+ --color-danger-strong: var(--red-700);
328
+ --color-info-strong: var(--blue-700);
329
+ --chart-1: #2a78d6;
330
+ --chart-2: #eb6834;
331
+ --chart-3: #1baf7a;
332
+ --chart-4: #eda100;
333
+ --chart-5: #e87ba4;
334
+ --chart-6: #008300;
335
+ --chart-7: #4a3aa7;
336
+ --chart-8: #e34948;
337
+ --chart-grid: var(--slate-200);
338
+ --chart-tick: var(--slate-400);
339
+ --focus-ring: var(--azure-600);
340
+ }
341
+ :root[data-density="compact"] {
342
+ --control-h: 2rem;
343
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@cahyo-dimas/freeday",
3
+ "version": "1.7.0",
4
+ "description": "Freeday — token-driven, framework-agnostic UI KIT (design source-of-truth).",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": true,
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/cahyo-dimas/freeday-ui-kit.git"
14
+ },
15
+ "homepage": "https://cahyo-dimas.github.io/freeday-ui-kit/docs/",
16
+ "bugs": {
17
+ "url": "https://github.com/cahyo-dimas/freeday-ui-kit/issues"
18
+ },
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "src",
25
+ "adapters",
26
+ "tokens/tokens.json",
27
+ "tokens/breakpoints.mjs",
28
+ "README.md",
29
+ "CHANGELOG.md"
30
+ ],
31
+ "exports": {
32
+ ".": "./dist/freeday.js",
33
+ "./css": "./dist/freeday.bundle.css",
34
+ "./css/components": "./dist/freeday.css",
35
+ "./tokens": "./dist/freeday.tokens.css",
36
+ "./breakpoints": "./tokens/breakpoints.mjs",
37
+ "./enhancers/*": "./dist/freeday-*.js",
38
+ "./vue": {
39
+ "types": "./adapters/vue/index.d.ts",
40
+ "default": "./adapters/vue/index.js"
41
+ },
42
+ "./react": {
43
+ "types": "./adapters/react/index.d.ts",
44
+ "default": "./adapters/react/index.js"
45
+ },
46
+ "./blazor": "./adapters/blazor/freeday-blazor.js",
47
+ "./package.json": "./package.json"
48
+ },
49
+ "peerDependencies": {
50
+ "react": ">=18",
51
+ "vue": "^3.4.0"
52
+ },
53
+ "peerDependenciesMeta": {
54
+ "vue": {
55
+ "optional": true
56
+ },
57
+ "react": {
58
+ "optional": true
59
+ }
60
+ },
61
+ "scripts": {
62
+ "build": "node tokens/build.mjs",
63
+ "test": "node --test",
64
+ "prepack": "node tokens/build.mjs",
65
+ "version": "node tokens/build.mjs && git add dist",
66
+ "typecheck:react": "tsc -p adapters/react/tsconfig.json --noEmit"
67
+ },
68
+ "devDependencies": {
69
+ "@types/react": "^19.2.17",
70
+ "typescript": "^7.0.2"
71
+ }
72
+ }
package/src/base.css ADDED
@@ -0,0 +1,20 @@
1
+ /* Freeday base layer — reset ringan + default via token */
2
+ *, *::before, *::after { box-sizing: border-box; }
3
+ html { -webkit-text-size-adjust: 100%; }
4
+ body {
5
+ margin: 0;
6
+ font-family: var(--font-body);
7
+ font-size: var(--text-base);
8
+ line-height: var(--leading-normal);
9
+ color: var(--color-text);
10
+ background: var(--color-surface);
11
+ -webkit-font-smoothing: antialiased;
12
+ }
13
+ h1, h2, h3, h4 { font-family: var(--font-display); font-weight: var(--weight-bold); letter-spacing: var(--tracking-tighter); line-height: var(--leading-snug); margin: 0; }
14
+ a { color: var(--color-primary); }
15
+ :focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-width); border-radius: var(--radius-xs); }
16
+ :where(button, input, select, textarea) { font: inherit; }
17
+ .fdy-visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
18
+ @media (prefers-reduced-motion: reduce) {
19
+ *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
20
+ }
File without changes
@@ -0,0 +1,13 @@
1
+ /* Freeday — Accordion (native <details>/<summary>, zero-JS) */
2
+ .fdy-accordion{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);overflow:hidden;background:var(--color-surface);}
3
+ .fdy-accordion__item + .fdy-accordion__item{border-top:var(--bw) solid var(--color-border);}
4
+ .fdy-accordion__item > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);font-weight:var(--weight-medium);color:var(--color-text);}
5
+ .fdy-accordion__item > summary::-webkit-details-marker{display:none;}
6
+ .fdy-accordion__item > summary::after{content:"";margin-left:auto;margin-top:-.15rem;flex:none;width:.5rem;height:.5rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(45deg);transition:transform var(--dur-fast) var(--ease-standard);}
7
+ .fdy-accordion__item[open] > summary::after{transform:rotate(225deg);margin-top:.1rem;}
8
+ .fdy-accordion__item > summary:hover{background:var(--color-surface-2);}
9
+ .fdy-accordion__item > summary:focus-visible{outline:none;box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
10
+ .fdy-accordion__panel{padding:0 var(--space-4) var(--space-4);color:var(--color-text-muted);font-size:var(--text-sm);line-height:var(--leading-normal);}
11
+ /* Content reveal on open (fade + rise). Native <details> can't animate its own height cross-
12
+ * browser without JS, so we animate the revealed panel instead — cheap, safe, reduced-motion gated. */
13
+ @media (prefers-reduced-motion:no-preference){.fdy-accordion__item[open] > .fdy-accordion__panel{animation:fdy-combo-in var(--dur-base) var(--ease-standard);}}
@@ -0,0 +1,18 @@
1
+ /* Freeday — Alert (inline) */
2
+ .fdy-alert{display:flex;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);border:var(--bw) solid var(--color-border);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface-2);}
3
+ .fdy-alert__icon{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-top:.05rem;}
4
+ .fdy-alert__icon svg{width:100%;height:100%;}
5
+ .fdy-alert__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);}
6
+ .fdy-alert__title{font-weight:var(--weight-semibold);color:var(--color-text);}
7
+ .fdy-alert__text{color:var(--color-text);line-height:var(--leading-normal);}
8
+ .fdy-alert__close{flex:none;align-self:flex-start;border:0;background:transparent;color:var(--color-text-muted);cursor:pointer;font-size:var(--text-lg);line-height:1;padding:0 var(--space-1);border-radius:var(--radius-sm);}
9
+ .fdy-alert__close:hover{color:var(--color-text);}
10
+ .fdy-alert__close:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
11
+ .fdy-alert--info{background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
12
+ .fdy-alert--info .fdy-alert__title,.fdy-alert--info .fdy-alert__icon{color:var(--color-info-strong);}
13
+ .fdy-alert--success{background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
14
+ .fdy-alert--success .fdy-alert__title,.fdy-alert--success .fdy-alert__icon{color:var(--color-success-strong);}
15
+ .fdy-alert--warning{background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
16
+ .fdy-alert--warning .fdy-alert__title,.fdy-alert--warning .fdy-alert__icon{color:var(--color-warning-strong);}
17
+ .fdy-alert--danger{background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
18
+ .fdy-alert--danger .fdy-alert__title,.fdy-alert--danger .fdy-alert__icon{color:var(--color-danger-strong);}
@@ -0,0 +1,88 @@
1
+ /* Freeday — App Shell.
2
+ * Natural document scroll: the shell grows with content and the PAGE scrolls,
3
+ * while the sidebar and topbar are position:sticky so they stay in view. No
4
+ * fixed-height / internal-scroll trickery (that leaves a white gap if the host
5
+ * page can still scroll). Structure: .fdy-app > (.fdy-app__sidebar, .fdy-app__content
6
+ * > (.fdy-app__topbar, .fdy-app__main)). The __content wrapper gives the sticky
7
+ * topbar a tall containing block so it can travel — a bare grid cell can't. */
8
+ .fdy-app{display:flex;align-items:stretch;min-height:100vh;background:var(--color-surface-2);}
9
+ .fdy-app__sidebar{position:sticky;top:0;align-self:flex-start;height:100vh;overflow:hidden;flex:none;width:15.5rem;box-sizing:border-box;background:var(--color-surface);border-right:var(--bw) solid var(--color-border);display:flex;flex-direction:column;transition:width var(--dur-slow) var(--ease-standard),border-right-width var(--dur-slow) var(--ease-standard);}
10
+ .fdy-app__content{flex:1;min-width:0;display:flex;flex-direction:column;}
11
+ /* Brand is a fixed header — same height as the topbar so they align, and only
12
+ * the nav below it scrolls. Bare text (no children) renders as one bold
13
+ * display line via the rules on .fdy-app__brand itself. For a mark + two-line
14
+ * title/subtitle, add structured children mirroring .fdy-appbar__brand:
15
+ * <div class="fdy-app__brand"><svg class="fdy-app__brand-mark">…</svg>
16
+ * <div class="fdy-app__brand-text">
17
+ * <span class="fdy-app__brand-title">…</span>
18
+ * <span class="fdy-app__brand-subtitle">…</span>
19
+ * </div></div> */
20
+ .fdy-app__brand{flex:none;display:flex;align-items:center;gap:var(--space-2);box-sizing:border-box;min-height:var(--space-16);font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);text-decoration:none;padding:0 var(--space-4);border-bottom:var(--bw) solid var(--color-border);}
21
+ .fdy-app__brand-mark{flex:none;width:1.5rem;height:1.5rem;}
22
+ .fdy-app__brand-mark svg{display:block;width:100%;height:100%;}
23
+ .fdy-app__brand-text{display:flex;flex-direction:column;min-width:0;}
24
+ .fdy-app__brand-title{display:block;font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
25
+ .fdy-app__brand-subtitle{display:block;font-size:var(--text-xs);font-weight:var(--weight-regular);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
26
+ .fdy-nav{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:2px;padding:var(--space-3) var(--space-3) var(--space-6);}
27
+ .fdy-nav__item{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);text-decoration:none;cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
28
+ .fdy-nav__item:hover{background:var(--color-surface-2);color:var(--color-text);}
29
+ /* Active indicator stays in the primary ramp so it never clashes with a re-themed accent. */
30
+ .fdy-nav__item[aria-current="page"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
31
+ .fdy-nav__item:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
32
+ /* Sidebar-menu extras: per-node icon (leading), count badge (trailing), and a
33
+ * text label that truncates. Any of these are optional — a bare text item works. */
34
+ .fdy-nav__icon{flex:none;display:inline-flex;width:1.15rem;height:1.15rem;}
35
+ .fdy-nav__icon svg{display:block;width:100%;height:100%;}
36
+ .fdy-nav__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
37
+ .fdy-nav__badge{flex:none;margin-left:auto;min-width:1.25rem;height:1.25rem;padding:0 6px;display:inline-flex;align-items:center;justify-content:center;font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;border-radius:var(--radius-full);background:var(--color-surface-3);color:var(--color-text-muted);}
38
+ .fdy-nav__item[aria-current="page"] .fdy-nav__badge{background:var(--color-primary);color:var(--color-on-primary);}
39
+ /* Collapsible section: <details class="fdy-nav__group"><summary class="fdy-nav__grouplabel"> */
40
+ .fdy-nav__group{margin:0;}
41
+ .fdy-nav__group + .fdy-nav__group,.fdy-nav__item + .fdy-nav__group{border-top:var(--bw) solid var(--color-border-muted);margin-top:var(--space-1);padding-top:var(--space-1);}
42
+ .fdy-nav__grouplabel{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-3) var(--space-3) var(--space-1);font-size:var(--text-xs);text-transform:uppercase;letter-spacing:var(--tracking-wide);font-weight:var(--weight-semibold);color:var(--color-text-subtle);}
43
+ .fdy-nav__grouplabel::-webkit-details-marker{display:none;}
44
+ .fdy-nav__grouplabel:hover{color:var(--color-text-muted);}
45
+ .fdy-nav__grouplabel:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
46
+ .fdy-nav__grouplabel::after{content:"";flex:none;width:.45rem;height:.45rem;margin-right:var(--space-1);border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform var(--dur-fast) var(--ease-standard);opacity:.7;}
47
+ .fdy-nav__group[open] > .fdy-nav__grouplabel::after{transform:rotate(45deg);}
48
+ /* --flat: calmer, non-collapsible grouped nav — hide the caret, drop the
49
+ * inter-group divider and the collapse cursor. Works on native <details> groups
50
+ * (caret just hidden) and on static <div>/<p> groups (never collapsible). */
51
+ .fdy-nav--flat .fdy-nav__grouplabel::after{display:none;}
52
+ .fdy-nav--flat .fdy-nav__group + .fdy-nav__group,.fdy-nav--flat .fdy-nav__item + .fdy-nav__group{border-top:0;}
53
+ .fdy-nav--flat .fdy-nav__grouplabel{cursor:default;}
54
+ /* Collapsible item (nested tree): <details class="fdy-nav__tree"><summary class="fdy-nav__item"> */
55
+ .fdy-nav__tree{margin:0;}
56
+ .fdy-nav__tree > summary{list-style:none;}
57
+ .fdy-nav__tree > summary::-webkit-details-marker{display:none;}
58
+ .fdy-nav__tree > summary .fdy-nav__caret{flex:none;margin-left:auto;width:.4rem;height:.4rem;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform var(--dur-fast) var(--ease-standard);opacity:.6;}
59
+ .fdy-nav__tree[open] > summary .fdy-nav__caret{transform:rotate(45deg);}
60
+ .fdy-nav__sub{display:flex;flex-direction:column;gap:2px;padding-left:calc(var(--space-3) + 1.15rem);margin-top:2px;}
61
+ /* Collapse toggle (hamburger) — sits in the topbar; collapses the sidebar. */
62
+ .fdy-app__navtoggle{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;flex:none;padding:0;border:0;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
63
+ .fdy-app__navtoggle:hover{background:var(--color-surface-2);color:var(--color-text);}
64
+ .fdy-app__navtoggle:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-primary);}
65
+ .fdy-app__navtoggle svg{display:block;width:1.25rem;height:1.25rem;}
66
+ /* Desktop collapse: animate width -> 0 (content clips via overflow:hidden; the content area
67
+ * flexes in to fill). Not display:none, so the collapse/expand slides instead of snapping. */
68
+ @media (min-width:721px){.fdy-app--nav-collapsed .fdy-app__sidebar{width:0;border-right-width:0;}}
69
+ .fdy-app__topbar{position:sticky;top:0;z-index:20;min-height:var(--space-16);display:flex;align-items:center;gap:var(--space-3);padding:0 var(--space-8);background:var(--color-surface);border-bottom:var(--bw) solid var(--color-border);}
70
+ .fdy-app__title{font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
71
+ .fdy-app__main{flex:1;padding:var(--space-8);}
72
+ .fdy-skip{position:absolute;left:var(--space-2);top:var(--space-2);background:var(--color-primary);color:var(--color-on-primary);padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);z-index:100;transform:translateY(-250%);transition:transform var(--dur-fast) var(--ease-standard);}
73
+ .fdy-skip:focus{transform:translateY(0);}
74
+ /* --static: for a bounded/embedded shell (a demo box, not the whole page) —
75
+ * drop sticky so nothing escapes the box; sidebar stretches to fill it. */
76
+ .fdy-app--static .fdy-app__sidebar{position:static;height:auto;align-self:stretch;}
77
+ .fdy-app--static .fdy-app__topbar{position:static;}
78
+ /* Mobile: the sidebar becomes an off-canvas drawer opened by the topbar toggle. */
79
+ .fdy-app__backdrop{display:none;}
80
+ @media (max-width:720px){
81
+ .fdy-app__sidebar{position:fixed;top:0;left:0;bottom:0;height:100dvh;width:16rem;z-index:60;transform:translateX(-100%);transition:transform var(--dur-base) var(--ease-standard);box-shadow:var(--shadow-4);}
82
+ .fdy-app--nav-open .fdy-app__sidebar{transform:translateX(0);}
83
+ .fdy-app__backdrop{display:block;position:fixed;inset:0;z-index:55;background:rgba(8,10,20,.45);opacity:0;visibility:hidden;transition:opacity var(--dur-base) var(--ease-standard),visibility var(--dur-base) var(--ease-standard);}
84
+ .fdy-app--nav-open .fdy-app__backdrop{opacity:1;visibility:visible;}
85
+ .fdy-app__main{padding:var(--space-5);}
86
+ .fdy-app__topbar{padding:0 var(--space-4);}
87
+ }
88
+ @media (prefers-reduced-motion:reduce){.fdy-app__sidebar{transition:none;}}
@@ -0,0 +1,15 @@
1
+ /* Freeday — App bar (standalone top bar: brand · actions · spacer).
2
+ * Distinct from .fdy-app__topbar (which is bound to the shell grid). Use anywhere;
3
+ * sticky / elevated / dense / coloured via modifiers. Pure CSS. */
4
+ .fdy-appbar{display:flex;align-items:center;gap:var(--space-3);height:var(--space-16);padding:0 var(--space-4);background:var(--color-surface);color:var(--color-text);border-bottom:var(--bw) solid var(--color-border);}
5
+ .fdy-appbar--sticky{position:sticky;top:0;z-index:90;}
6
+ .fdy-appbar--elevated{border-bottom:0;box-shadow:var(--shadow-2);}
7
+ .fdy-appbar--dense{height:var(--space-12);}
8
+ .fdy-appbar--primary{background:var(--color-primary);color:var(--color-on-primary);border-bottom-color:transparent;}
9
+ .fdy-appbar__brand{display:inline-flex;align-items:center;gap:var(--space-2);font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:inherit;white-space:nowrap;}
10
+ .fdy-appbar__brand svg{display:block;width:1.5rem;height:1.5rem;}
11
+ .fdy-appbar__spacer{flex:1;}
12
+ .fdy-appbar__actions{display:inline-flex;align-items:center;gap:var(--space-1);}
13
+ /* Controls on a coloured app bar go on-colour (icons stay legible, hover is a light wash) */
14
+ .fdy-appbar--primary .fdy-btn--ghost{background:transparent;border-color:transparent;color:var(--color-on-primary);box-shadow:none;}
15
+ .fdy-appbar--primary .fdy-btn--ghost:hover{background:color-mix(in srgb,var(--color-on-primary) 16%,transparent);color:var(--color-on-primary);transform:none;}
@@ -0,0 +1,12 @@
1
+ /* Freeday — Autocomplete (text input + filtered suggestion listbox, APG editable combobox).
2
+ * Enhanced by freeday-autocomplete.js. */
3
+ .fdy-autocomplete{position:relative;display:block;max-width:22rem;}
4
+ .fdy-autocomplete__listbox{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:120;min-width:100%;max-height:16rem;overflow-y:auto;margin:0;padding:var(--space-1);list-style:none;background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
5
+ .fdy-autocomplete__listbox[hidden]{display:none;}
6
+ .fdy-autocomplete__option{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;white-space:nowrap;}
7
+ .fdy-autocomplete__option[hidden]{display:none;}
8
+ .fdy-autocomplete__option:hover,.fdy-autocomplete__option.is-highlighted{background:var(--color-surface-3);}
9
+ .fdy-autocomplete__option[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
10
+ .fdy-autocomplete__empty{padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-muted);}
11
+ .fdy-autocomplete__empty[hidden]{display:none;}
12
+ @media (prefers-reduced-motion:no-preference){.fdy-autocomplete__listbox:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
@@ -0,0 +1,8 @@
1
+ /* Freeday — Avatar */
2
+ .fdy-avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;width:2.5rem;height:2.5rem;border-radius:var(--radius-full);background:var(--color-primary-soft);color:var(--color-primary-strong);font-family:var(--font-body);font-weight:var(--weight-semibold);font-size:var(--text-sm);line-height:1;overflow:hidden;user-select:none;}
3
+ .fdy-avatar img{width:100%;height:100%;object-fit:cover;}
4
+ .fdy-avatar--sm{width:2rem;height:2rem;font-size:var(--text-xs);}
5
+ .fdy-avatar--lg{width:3.5rem;height:3.5rem;font-size:var(--text-lg);}
6
+ .fdy-avatar-group{display:inline-flex;}
7
+ .fdy-avatar-group .fdy-avatar{border:2px solid var(--color-surface);margin-left:calc(var(--space-2)*-1);}
8
+ .fdy-avatar-group .fdy-avatar:first-child{margin-left:0;}
@@ -0,0 +1,27 @@
1
+ /* Freeday — Badge */
2
+ .fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
3
+ .fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
4
+ .fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
5
+ .fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
6
+ .fdy-badge--info{color:var(--color-info-strong);background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
7
+ .fdy-badge--outline{background:transparent;border-color:var(--color-border-strong);color:var(--color-text-muted);box-shadow:none;}
8
+
9
+ /* Overlay badge — anchors a small count/dot/icon badge to a corner of any element
10
+ * (icon, button, text). Wrap the content in .fdy-badge-wrap; add .fdy-badge-ov as a
11
+ * sibling. Default is a solid neutral pill; colour + dot + position via modifiers. */
12
+ .fdy-badge-wrap{position:relative;display:inline-flex;vertical-align:middle;}
13
+ .fdy-badge-ov{position:absolute;top:0;right:0;transform:translate(50%,-50%);z-index:1;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 var(--space-1);border-radius:var(--radius-full);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;color:var(--color-inverse-text);background:var(--color-inverse-surface);border:2px solid var(--color-surface);}
14
+ .fdy-badge-ov svg{display:block;width:.75rem;height:.75rem;}
15
+ .fdy-badge-ov--dot{min-width:0;width:.75rem;height:.75rem;padding:0;}
16
+ /* Solid colours safe for count/text (on-* tokens, AA in light & dark) */
17
+ .fdy-badge-ov--primary{background:var(--color-primary);color:var(--color-on-primary);}
18
+ .fdy-badge-ov--danger{background:var(--color-danger-btn);color:var(--color-on-danger);}
19
+ /* Dot-oriented accents (for dots — plain text on these is not guaranteed AA) */
20
+ .fdy-badge-ov--accent{background:var(--color-accent);}
21
+ .fdy-badge-ov--info{background:var(--color-info);}
22
+ .fdy-badge-ov--success{background:var(--color-success);}
23
+ .fdy-badge-ov--warning{background:var(--color-warning);}
24
+ /* Anchor position */
25
+ .fdy-badge-ov--top-left{right:auto;left:0;transform:translate(-50%,-50%);}
26
+ .fdy-badge-ov--bottom-right{top:auto;bottom:0;transform:translate(50%,50%);}
27
+ .fdy-badge-ov--bottom-left{top:auto;bottom:0;right:auto;left:0;transform:translate(-50%,50%);}
@@ -0,0 +1,9 @@
1
+ /* Freeday — Breadcrumb */
2
+ .fdy-breadcrumb{font-size:var(--text-sm);}
3
+ .fdy-breadcrumb__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);list-style:none;margin:0;padding:0;}
4
+ .fdy-breadcrumb__item{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--color-text-muted);}
5
+ .fdy-breadcrumb__link{color:var(--color-text-muted);text-decoration:none;border-radius:var(--radius-sm);}
6
+ .fdy-breadcrumb__link:hover{color:var(--color-primary-strong);text-decoration:underline;}
7
+ .fdy-breadcrumb__link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
8
+ .fdy-breadcrumb__item[aria-current="page"]{color:var(--color-text);font-weight:var(--weight-medium);}
9
+ .fdy-breadcrumb__sep{color:var(--color-text-subtle);user-select:none;}