@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,1352 @@
1
+ /* Freeday — tokens + components in one file. GENERATED by tokens/build.mjs. */
2
+ /* Freeday tokens — GENERATED by tokens/build.mjs. Do not edit by hand. */
3
+ :root {
4
+ --azure-50: #eff4ff;
5
+ --azure-100: #dbe6fe;
6
+ --azure-200: #bdd2fd;
7
+ --azure-300: #90b3fb;
8
+ --azure-400: #5c8bf6;
9
+ --azure-500: #3467ec;
10
+ --azure-600: #2050d8;
11
+ --azure-700: #1c40b0;
12
+ --azure-800: #1c398c;
13
+ --azure-900: #1c336e;
14
+ --azure-950: #131e42;
15
+ --slate-0: #ffffff;
16
+ --slate-50: #f7f8fa;
17
+ --slate-100: #eef0f4;
18
+ --slate-200: #e0e3ea;
19
+ --slate-300: #cbd0da;
20
+ --slate-400: #99a1b3;
21
+ --slate-500: #6b7488;
22
+ --slate-600: #4d5568;
23
+ --slate-700: #3a4152;
24
+ --slate-800: #262b38;
25
+ --slate-900: #171b26;
26
+ --slate-950: #0e111a;
27
+ --sky-50: #eff6fd;
28
+ --sky-100: #d6e9fb;
29
+ --sky-200: #b0d4f6;
30
+ --sky-300: #7bbdef;
31
+ --sky-400: #47a1e6;
32
+ --sky-500: #1a86dc;
33
+ --sky-600: #0078d4;
34
+ --sky-700: #0061ac;
35
+ --sky-800: #004d88;
36
+ --sky-900: #003a67;
37
+ --red-100: #fee2e2;
38
+ --red-300: #fca5a5;
39
+ --red-400: #f87171;
40
+ --red-500: #ef4444;
41
+ --red-600: #dc2626;
42
+ --red-700: #b91c1c;
43
+ --amber-100: #fef3c7;
44
+ --amber-400: #fbbf24;
45
+ --amber-500: #f59e0b;
46
+ --amber-600: #d97706;
47
+ --amber-700: #b45309;
48
+ --amber-800: #92400e;
49
+ --green-100: #dcfce7;
50
+ --green-400: #4ade80;
51
+ --green-500: #22c55e;
52
+ --green-600: #16a34a;
53
+ --green-700: #15803d;
54
+ --green-800: #166534;
55
+ --blue-100: #dbeafe;
56
+ --blue-300: #93c5fd;
57
+ --blue-400: #60a5fa;
58
+ --blue-500: #3b82f6;
59
+ --blue-600: #2563eb;
60
+ --blue-700: #1d4ed8;
61
+ --font-display: 'Sora', ui-sans-serif, system-ui, sans-serif;
62
+ --font-body: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
63
+ --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
64
+ --text-xs: 0.75rem;
65
+ --text-sm: 0.875rem;
66
+ --text-base: 1rem;
67
+ --text-lg: 1.125rem;
68
+ --text-xl: 1.25rem;
69
+ --text-2xl: 1.5625rem;
70
+ --text-3xl: 1.9375rem;
71
+ --text-4xl: 2.4375rem;
72
+ --text-5xl: 3.0625rem;
73
+ --leading-tight: 1.2;
74
+ --leading-snug: 1.35;
75
+ --leading-normal: 1.55;
76
+ --leading-loose: 1.75;
77
+ --tracking-tighter: -0.03em;
78
+ --tracking-tight: -0.02em;
79
+ --tracking-normal: 0;
80
+ --tracking-wide: 0.06em;
81
+ --weight-regular: 400;
82
+ --weight-medium: 500;
83
+ --weight-semibold: 600;
84
+ --weight-bold: 700;
85
+ --space-0: 0;
86
+ --space-1: 0.25rem;
87
+ --space-2: 0.5rem;
88
+ --space-3: 0.75rem;
89
+ --space-4: 1rem;
90
+ --space-5: 1.25rem;
91
+ --space-6: 1.5rem;
92
+ --space-8: 2rem;
93
+ --space-10: 2.5rem;
94
+ --space-12: 3rem;
95
+ --space-16: 4rem;
96
+ --space-20: 5rem;
97
+ --space-24: 6rem;
98
+ --radius-xs: 3px;
99
+ --radius-sm: 4px;
100
+ --radius-md: 6px;
101
+ --radius-lg: 10px;
102
+ --radius-xl: 14px;
103
+ --radius-full: 999px;
104
+ --shadow-1: 0 1px 2px rgba(16,14,30,.06);
105
+ --shadow-2: 0 2px 6px rgba(16,14,30,.07),0 1px 2px rgba(16,14,30,.05);
106
+ --shadow-3: 0 4px 16px -2px rgba(16,14,30,.14),0 1px 3px rgba(16,14,30,.10);
107
+ --shadow-4: 0 24px 48px -12px rgba(16,14,30,.26),0 2px 8px rgba(16,14,30,.10);
108
+ --shadow-lift: 0 1px 2px rgba(16,14,30,.05),0 16px 34px -14px rgba(16,14,30,.24);
109
+ --shadow-lift-hover: 0 2px 4px rgba(16,14,30,.06),0 30px 50px -16px rgba(16,14,30,.33);
110
+ --dur-fast: 120ms;
111
+ --dur-base: 180ms;
112
+ --dur-slow: 280ms;
113
+ --ease-standard: cubic-bezier(.2,0,0,1);
114
+ --ease-spring: cubic-bezier(.2,.8,.2,1);
115
+ --control-h: 2.5rem;
116
+ --control-box: 1.15rem;
117
+ --control-switch-w: 2.4rem;
118
+ --control-switch-h: 1.35rem;
119
+ --bw: 1px;
120
+ --color-primary: var(--azure-600);
121
+ --color-primary-hover: var(--azure-700);
122
+ --color-primary-active: var(--azure-800);
123
+ --color-on-primary: var(--slate-0);
124
+ --color-primary-soft: var(--azure-50);
125
+ --color-primary-border: var(--azure-100);
126
+ --color-accent: var(--sky-600);
127
+ --color-accent-hover: var(--sky-700);
128
+ --color-on-accent: var(--slate-0);
129
+ --color-on-danger: var(--slate-0);
130
+ --color-danger-btn: var(--red-600);
131
+ --color-surface: var(--slate-0);
132
+ --color-surface-2: var(--slate-50);
133
+ --color-surface-3: var(--slate-100);
134
+ --color-text: var(--slate-900);
135
+ --color-text-muted: var(--slate-600);
136
+ --color-text-subtle: var(--slate-500);
137
+ --color-on-brand: var(--slate-0);
138
+ --color-border: var(--slate-200);
139
+ --color-border-strong: var(--slate-300);
140
+ --color-border-muted: var(--slate-100);
141
+ --color-control-border: var(--slate-500);
142
+ --color-switch-thumb: var(--slate-0);
143
+ --color-shadow-inset: rgba(16,14,30,.06);
144
+ --color-inverse-surface: var(--slate-900);
145
+ --color-inverse-text: var(--slate-0);
146
+ --color-success: var(--green-600);
147
+ --color-success-soft: var(--green-100);
148
+ --color-warning: #c2740a;
149
+ --color-warning-soft: var(--amber-100);
150
+ --color-danger: var(--red-600);
151
+ --color-danger-soft: var(--red-100);
152
+ --color-info: var(--blue-600);
153
+ --color-info-soft: var(--blue-100);
154
+ --color-primary-strong: var(--azure-700);
155
+ --color-success-strong: var(--green-800);
156
+ --color-warning-strong: var(--amber-800);
157
+ --color-danger-strong: var(--red-700);
158
+ --color-info-strong: var(--blue-700);
159
+ --chart-1: #2a78d6;
160
+ --chart-2: #eb6834;
161
+ --chart-3: #1baf7a;
162
+ --chart-4: #eda100;
163
+ --chart-5: #e87ba4;
164
+ --chart-6: #008300;
165
+ --chart-7: #4a3aa7;
166
+ --chart-8: #e34948;
167
+ --chart-grid: var(--slate-200);
168
+ --chart-tick: var(--slate-400);
169
+ --focus-ring: var(--azure-600);
170
+ --focus-ring-width: 2px;
171
+ }
172
+ @media (prefers-color-scheme: dark) {
173
+ :root:not([data-theme="light"]) {
174
+ --shadow-1: 0 1px 2px rgba(0,0,0,.4);
175
+ --shadow-2: 0 2px 6px rgba(0,0,0,.45);
176
+ --shadow-3: 0 6px 20px -2px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.5);
177
+ --shadow-4: 0 28px 56px -12px rgba(0,0,0,.72),0 2px 8px rgba(0,0,0,.5);
178
+ --shadow-lift: 0 1px 2px rgba(0,0,0,.5),0 18px 38px -14px rgba(0,0,0,.72);
179
+ --shadow-lift-hover: 0 3px 6px rgba(0,0,0,.55),0 32px 56px -16px rgba(0,0,0,.82);
180
+ --color-primary: var(--azure-500);
181
+ --color-primary-hover: var(--azure-400);
182
+ --color-primary-active: var(--azure-300);
183
+ --color-on-primary: var(--slate-0);
184
+ --color-primary-soft: rgba(32,80,216,.20);
185
+ --color-primary-border: rgba(92,139,246,.28);
186
+ --color-accent: var(--sky-400);
187
+ --color-accent-hover: var(--sky-300);
188
+ --color-on-accent: #06233f;
189
+ --color-on-danger: var(--slate-0);
190
+ --color-danger-btn: var(--red-600);
191
+ --color-surface: var(--slate-950);
192
+ --color-surface-2: var(--slate-900);
193
+ --color-surface-3: var(--slate-800);
194
+ --color-text: var(--slate-100);
195
+ --color-text-muted: var(--slate-400);
196
+ --color-text-subtle: var(--slate-500);
197
+ --color-on-brand: var(--slate-0);
198
+ --color-border: var(--slate-800);
199
+ --color-border-strong: var(--slate-700);
200
+ --color-border-muted: #1c2130;
201
+ --color-control-border: var(--slate-500);
202
+ --color-inverse-surface: var(--slate-100);
203
+ --color-inverse-text: var(--slate-900);
204
+ --color-success: var(--green-500);
205
+ --color-success-soft: rgba(34,197,94,.18);
206
+ --color-warning: var(--amber-500);
207
+ --color-warning-soft: rgba(234,179,8,.18);
208
+ --color-danger: var(--red-400);
209
+ --color-danger-soft: rgba(248,113,113,.18);
210
+ --color-info: var(--blue-400);
211
+ --color-info-soft: rgba(96,165,250,.18);
212
+ --color-primary-strong: var(--azure-300);
213
+ --color-success-strong: var(--green-400);
214
+ --color-warning-strong: var(--amber-400);
215
+ --color-danger-strong: var(--red-300);
216
+ --color-info-strong: var(--blue-300);
217
+ --chart-1: #3987e5;
218
+ --chart-2: #d95926;
219
+ --chart-3: #199e70;
220
+ --chart-4: #c98500;
221
+ --chart-5: #d55181;
222
+ --chart-6: #008300;
223
+ --chart-7: #9085e9;
224
+ --chart-8: #e66767;
225
+ --chart-grid: var(--slate-800);
226
+ --chart-tick: var(--slate-600);
227
+ --focus-ring: var(--azure-400);
228
+ }
229
+ }
230
+ :root[data-theme="dark"] {
231
+ --shadow-1: 0 1px 2px rgba(0,0,0,.4);
232
+ --shadow-2: 0 2px 6px rgba(0,0,0,.45);
233
+ --shadow-3: 0 6px 20px -2px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.5);
234
+ --shadow-4: 0 28px 56px -12px rgba(0,0,0,.72),0 2px 8px rgba(0,0,0,.5);
235
+ --shadow-lift: 0 1px 2px rgba(0,0,0,.5),0 18px 38px -14px rgba(0,0,0,.72);
236
+ --shadow-lift-hover: 0 3px 6px rgba(0,0,0,.55),0 32px 56px -16px rgba(0,0,0,.82);
237
+ --color-primary: var(--azure-500);
238
+ --color-primary-hover: var(--azure-400);
239
+ --color-primary-active: var(--azure-300);
240
+ --color-on-primary: var(--slate-0);
241
+ --color-primary-soft: rgba(32,80,216,.20);
242
+ --color-primary-border: rgba(92,139,246,.28);
243
+ --color-accent: var(--sky-400);
244
+ --color-accent-hover: var(--sky-300);
245
+ --color-on-accent: #06233f;
246
+ --color-on-danger: var(--slate-0);
247
+ --color-danger-btn: var(--red-600);
248
+ --color-surface: var(--slate-950);
249
+ --color-surface-2: var(--slate-900);
250
+ --color-surface-3: var(--slate-800);
251
+ --color-text: var(--slate-100);
252
+ --color-text-muted: var(--slate-400);
253
+ --color-text-subtle: var(--slate-500);
254
+ --color-on-brand: var(--slate-0);
255
+ --color-border: var(--slate-800);
256
+ --color-border-strong: var(--slate-700);
257
+ --color-border-muted: #1c2130;
258
+ --color-control-border: var(--slate-500);
259
+ --color-inverse-surface: var(--slate-100);
260
+ --color-inverse-text: var(--slate-900);
261
+ --color-success: var(--green-500);
262
+ --color-success-soft: rgba(34,197,94,.18);
263
+ --color-warning: var(--amber-500);
264
+ --color-warning-soft: rgba(234,179,8,.18);
265
+ --color-danger: var(--red-400);
266
+ --color-danger-soft: rgba(248,113,113,.18);
267
+ --color-info: var(--blue-400);
268
+ --color-info-soft: rgba(96,165,250,.18);
269
+ --color-primary-strong: var(--azure-300);
270
+ --color-success-strong: var(--green-400);
271
+ --color-warning-strong: var(--amber-400);
272
+ --color-danger-strong: var(--red-300);
273
+ --color-info-strong: var(--blue-300);
274
+ --chart-1: #3987e5;
275
+ --chart-2: #d95926;
276
+ --chart-3: #199e70;
277
+ --chart-4: #c98500;
278
+ --chart-5: #d55181;
279
+ --chart-6: #008300;
280
+ --chart-7: #9085e9;
281
+ --chart-8: #e66767;
282
+ --chart-grid: var(--slate-800);
283
+ --chart-tick: var(--slate-600);
284
+ --focus-ring: var(--azure-400);
285
+ }
286
+ :root[data-theme="light"] {
287
+ --shadow-1: 0 1px 2px rgba(16,14,30,.06);
288
+ --shadow-2: 0 2px 6px rgba(16,14,30,.07),0 1px 2px rgba(16,14,30,.05);
289
+ --shadow-3: 0 4px 16px -2px rgba(16,14,30,.14),0 1px 3px rgba(16,14,30,.10);
290
+ --shadow-4: 0 24px 48px -12px rgba(16,14,30,.26),0 2px 8px rgba(16,14,30,.10);
291
+ --shadow-lift: 0 1px 2px rgba(16,14,30,.05),0 16px 34px -14px rgba(16,14,30,.24);
292
+ --shadow-lift-hover: 0 2px 4px rgba(16,14,30,.06),0 30px 50px -16px rgba(16,14,30,.33);
293
+ --color-primary: var(--azure-600);
294
+ --color-primary-hover: var(--azure-700);
295
+ --color-primary-active: var(--azure-800);
296
+ --color-on-primary: var(--slate-0);
297
+ --color-primary-soft: var(--azure-50);
298
+ --color-primary-border: var(--azure-100);
299
+ --color-accent: var(--sky-600);
300
+ --color-accent-hover: var(--sky-700);
301
+ --color-on-accent: var(--slate-0);
302
+ --color-on-danger: var(--slate-0);
303
+ --color-danger-btn: var(--red-600);
304
+ --color-surface: var(--slate-0);
305
+ --color-surface-2: var(--slate-50);
306
+ --color-surface-3: var(--slate-100);
307
+ --color-text: var(--slate-900);
308
+ --color-text-muted: var(--slate-600);
309
+ --color-text-subtle: var(--slate-500);
310
+ --color-on-brand: var(--slate-0);
311
+ --color-border: var(--slate-200);
312
+ --color-border-strong: var(--slate-300);
313
+ --color-border-muted: var(--slate-100);
314
+ --color-control-border: var(--slate-500);
315
+ --color-inverse-surface: var(--slate-900);
316
+ --color-inverse-text: var(--slate-0);
317
+ --color-success: var(--green-600);
318
+ --color-success-soft: var(--green-100);
319
+ --color-warning: #c2740a;
320
+ --color-warning-soft: var(--amber-100);
321
+ --color-danger: var(--red-600);
322
+ --color-danger-soft: var(--red-100);
323
+ --color-info: var(--blue-600);
324
+ --color-info-soft: var(--blue-100);
325
+ --color-primary-strong: var(--azure-700);
326
+ --color-success-strong: var(--green-800);
327
+ --color-warning-strong: var(--amber-800);
328
+ --color-danger-strong: var(--red-700);
329
+ --color-info-strong: var(--blue-700);
330
+ --chart-1: #2a78d6;
331
+ --chart-2: #eb6834;
332
+ --chart-3: #1baf7a;
333
+ --chart-4: #eda100;
334
+ --chart-5: #e87ba4;
335
+ --chart-6: #008300;
336
+ --chart-7: #4a3aa7;
337
+ --chart-8: #e34948;
338
+ --chart-grid: var(--slate-200);
339
+ --chart-tick: var(--slate-400);
340
+ --focus-ring: var(--azure-600);
341
+ }
342
+ :root[data-density="compact"] {
343
+ --control-h: 2rem;
344
+ }
345
+
346
+ /* Freeday components — GENERATED by tokens/build.mjs. Do not edit by hand. */
347
+ /* Freeday base layer — reset ringan + default via token */
348
+ *, *::before, *::after { box-sizing: border-box; }
349
+ html { -webkit-text-size-adjust: 100%; }
350
+ body {
351
+ margin: 0;
352
+ font-family: var(--font-body);
353
+ font-size: var(--text-base);
354
+ line-height: var(--leading-normal);
355
+ color: var(--color-text);
356
+ background: var(--color-surface);
357
+ -webkit-font-smoothing: antialiased;
358
+ }
359
+ 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; }
360
+ a { color: var(--color-primary); }
361
+ :focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-width); border-radius: var(--radius-xs); }
362
+ :where(button, input, select, textarea) { font: inherit; }
363
+ .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; }
364
+ @media (prefers-reduced-motion: reduce) {
365
+ *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
366
+ }
367
+
368
+ /* Freeday — Accordion (native <details>/<summary>, zero-JS) */
369
+ .fdy-accordion{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);overflow:hidden;background:var(--color-surface);}
370
+ .fdy-accordion__item + .fdy-accordion__item{border-top:var(--bw) solid var(--color-border);}
371
+ .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);}
372
+ .fdy-accordion__item > summary::-webkit-details-marker{display:none;}
373
+ .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);}
374
+ .fdy-accordion__item[open] > summary::after{transform:rotate(225deg);margin-top:.1rem;}
375
+ .fdy-accordion__item > summary:hover{background:var(--color-surface-2);}
376
+ .fdy-accordion__item > summary:focus-visible{outline:none;box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
377
+ .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);}
378
+ /* Content reveal on open (fade + rise). Native <details> can't animate its own height cross-
379
+ * browser without JS, so we animate the revealed panel instead — cheap, safe, reduced-motion gated. */
380
+ @media (prefers-reduced-motion:no-preference){.fdy-accordion__item[open] > .fdy-accordion__panel{animation:fdy-combo-in var(--dur-base) var(--ease-standard);}}
381
+
382
+ /* Freeday — Alert (inline) */
383
+ .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);}
384
+ .fdy-alert__icon{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-top:.05rem;}
385
+ .fdy-alert__icon svg{width:100%;height:100%;}
386
+ .fdy-alert__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);}
387
+ .fdy-alert__title{font-weight:var(--weight-semibold);color:var(--color-text);}
388
+ .fdy-alert__text{color:var(--color-text);line-height:var(--leading-normal);}
389
+ .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);}
390
+ .fdy-alert__close:hover{color:var(--color-text);}
391
+ .fdy-alert__close:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
392
+ .fdy-alert--info{background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
393
+ .fdy-alert--info .fdy-alert__title,.fdy-alert--info .fdy-alert__icon{color:var(--color-info-strong);}
394
+ .fdy-alert--success{background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
395
+ .fdy-alert--success .fdy-alert__title,.fdy-alert--success .fdy-alert__icon{color:var(--color-success-strong);}
396
+ .fdy-alert--warning{background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
397
+ .fdy-alert--warning .fdy-alert__title,.fdy-alert--warning .fdy-alert__icon{color:var(--color-warning-strong);}
398
+ .fdy-alert--danger{background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
399
+ .fdy-alert--danger .fdy-alert__title,.fdy-alert--danger .fdy-alert__icon{color:var(--color-danger-strong);}
400
+
401
+ /* Freeday — App Shell.
402
+ * Natural document scroll: the shell grows with content and the PAGE scrolls,
403
+ * while the sidebar and topbar are position:sticky so they stay in view. No
404
+ * fixed-height / internal-scroll trickery (that leaves a white gap if the host
405
+ * page can still scroll). Structure: .fdy-app > (.fdy-app__sidebar, .fdy-app__content
406
+ * > (.fdy-app__topbar, .fdy-app__main)). The __content wrapper gives the sticky
407
+ * topbar a tall containing block so it can travel — a bare grid cell can't. */
408
+ .fdy-app{display:flex;align-items:stretch;min-height:100vh;background:var(--color-surface-2);}
409
+ .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);}
410
+ .fdy-app__content{flex:1;min-width:0;display:flex;flex-direction:column;}
411
+ /* Brand is a fixed header — same height as the topbar so they align, and only
412
+ * the nav below it scrolls. Bare text (no children) renders as one bold
413
+ * display line via the rules on .fdy-app__brand itself. For a mark + two-line
414
+ * title/subtitle, add structured children mirroring .fdy-appbar__brand:
415
+ * <div class="fdy-app__brand"><svg class="fdy-app__brand-mark">…</svg>
416
+ * <div class="fdy-app__brand-text">
417
+ * <span class="fdy-app__brand-title">…</span>
418
+ * <span class="fdy-app__brand-subtitle">…</span>
419
+ * </div></div> */
420
+ .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);}
421
+ .fdy-app__brand-mark{flex:none;width:1.5rem;height:1.5rem;}
422
+ .fdy-app__brand-mark svg{display:block;width:100%;height:100%;}
423
+ .fdy-app__brand-text{display:flex;flex-direction:column;min-width:0;}
424
+ .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;}
425
+ .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;}
426
+ .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);}
427
+ .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);}
428
+ .fdy-nav__item:hover{background:var(--color-surface-2);color:var(--color-text);}
429
+ /* Active indicator stays in the primary ramp so it never clashes with a re-themed accent. */
430
+ .fdy-nav__item[aria-current="page"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
431
+ .fdy-nav__item:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
432
+ /* Sidebar-menu extras: per-node icon (leading), count badge (trailing), and a
433
+ * text label that truncates. Any of these are optional — a bare text item works. */
434
+ .fdy-nav__icon{flex:none;display:inline-flex;width:1.15rem;height:1.15rem;}
435
+ .fdy-nav__icon svg{display:block;width:100%;height:100%;}
436
+ .fdy-nav__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
437
+ .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);}
438
+ .fdy-nav__item[aria-current="page"] .fdy-nav__badge{background:var(--color-primary);color:var(--color-on-primary);}
439
+ /* Collapsible section: <details class="fdy-nav__group"><summary class="fdy-nav__grouplabel"> */
440
+ .fdy-nav__group{margin:0;}
441
+ .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);}
442
+ .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);}
443
+ .fdy-nav__grouplabel::-webkit-details-marker{display:none;}
444
+ .fdy-nav__grouplabel:hover{color:var(--color-text-muted);}
445
+ .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);}
446
+ .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;}
447
+ .fdy-nav__group[open] > .fdy-nav__grouplabel::after{transform:rotate(45deg);}
448
+ /* --flat: calmer, non-collapsible grouped nav — hide the caret, drop the
449
+ * inter-group divider and the collapse cursor. Works on native <details> groups
450
+ * (caret just hidden) and on static <div>/<p> groups (never collapsible). */
451
+ .fdy-nav--flat .fdy-nav__grouplabel::after{display:none;}
452
+ .fdy-nav--flat .fdy-nav__group + .fdy-nav__group,.fdy-nav--flat .fdy-nav__item + .fdy-nav__group{border-top:0;}
453
+ .fdy-nav--flat .fdy-nav__grouplabel{cursor:default;}
454
+ /* Collapsible item (nested tree): <details class="fdy-nav__tree"><summary class="fdy-nav__item"> */
455
+ .fdy-nav__tree{margin:0;}
456
+ .fdy-nav__tree > summary{list-style:none;}
457
+ .fdy-nav__tree > summary::-webkit-details-marker{display:none;}
458
+ .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;}
459
+ .fdy-nav__tree[open] > summary .fdy-nav__caret{transform:rotate(45deg);}
460
+ .fdy-nav__sub{display:flex;flex-direction:column;gap:2px;padding-left:calc(var(--space-3) + 1.15rem);margin-top:2px;}
461
+ /* Collapse toggle (hamburger) — sits in the topbar; collapses the sidebar. */
462
+ .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);}
463
+ .fdy-app__navtoggle:hover{background:var(--color-surface-2);color:var(--color-text);}
464
+ .fdy-app__navtoggle:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-primary);}
465
+ .fdy-app__navtoggle svg{display:block;width:1.25rem;height:1.25rem;}
466
+ /* Desktop collapse: animate width -> 0 (content clips via overflow:hidden; the content area
467
+ * flexes in to fill). Not display:none, so the collapse/expand slides instead of snapping. */
468
+ @media (min-width:721px){.fdy-app--nav-collapsed .fdy-app__sidebar{width:0;border-right-width:0;}}
469
+ .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);}
470
+ .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;}
471
+ .fdy-app__main{flex:1;padding:var(--space-8);}
472
+ .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);}
473
+ .fdy-skip:focus{transform:translateY(0);}
474
+ /* --static: for a bounded/embedded shell (a demo box, not the whole page) —
475
+ * drop sticky so nothing escapes the box; sidebar stretches to fill it. */
476
+ .fdy-app--static .fdy-app__sidebar{position:static;height:auto;align-self:stretch;}
477
+ .fdy-app--static .fdy-app__topbar{position:static;}
478
+ /* Mobile: the sidebar becomes an off-canvas drawer opened by the topbar toggle. */
479
+ .fdy-app__backdrop{display:none;}
480
+ @media (max-width:720px){
481
+ .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);}
482
+ .fdy-app--nav-open .fdy-app__sidebar{transform:translateX(0);}
483
+ .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);}
484
+ .fdy-app--nav-open .fdy-app__backdrop{opacity:1;visibility:visible;}
485
+ .fdy-app__main{padding:var(--space-5);}
486
+ .fdy-app__topbar{padding:0 var(--space-4);}
487
+ }
488
+ @media (prefers-reduced-motion:reduce){.fdy-app__sidebar{transition:none;}}
489
+
490
+ /* Freeday — App bar (standalone top bar: brand · actions · spacer).
491
+ * Distinct from .fdy-app__topbar (which is bound to the shell grid). Use anywhere;
492
+ * sticky / elevated / dense / coloured via modifiers. Pure CSS. */
493
+ .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);}
494
+ .fdy-appbar--sticky{position:sticky;top:0;z-index:90;}
495
+ .fdy-appbar--elevated{border-bottom:0;box-shadow:var(--shadow-2);}
496
+ .fdy-appbar--dense{height:var(--space-12);}
497
+ .fdy-appbar--primary{background:var(--color-primary);color:var(--color-on-primary);border-bottom-color:transparent;}
498
+ .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;}
499
+ .fdy-appbar__brand svg{display:block;width:1.5rem;height:1.5rem;}
500
+ .fdy-appbar__spacer{flex:1;}
501
+ .fdy-appbar__actions{display:inline-flex;align-items:center;gap:var(--space-1);}
502
+ /* Controls on a coloured app bar go on-colour (icons stay legible, hover is a light wash) */
503
+ .fdy-appbar--primary .fdy-btn--ghost{background:transparent;border-color:transparent;color:var(--color-on-primary);box-shadow:none;}
504
+ .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;}
505
+
506
+ /* Freeday — Autocomplete (text input + filtered suggestion listbox, APG editable combobox).
507
+ * Enhanced by freeday-autocomplete.js. */
508
+ .fdy-autocomplete{position:relative;display:block;max-width:22rem;}
509
+ .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);}
510
+ .fdy-autocomplete__listbox[hidden]{display:none;}
511
+ .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;}
512
+ .fdy-autocomplete__option[hidden]{display:none;}
513
+ .fdy-autocomplete__option:hover,.fdy-autocomplete__option.is-highlighted{background:var(--color-surface-3);}
514
+ .fdy-autocomplete__option[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
515
+ .fdy-autocomplete__empty{padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-muted);}
516
+ .fdy-autocomplete__empty[hidden]{display:none;}
517
+ @media (prefers-reduced-motion:no-preference){.fdy-autocomplete__listbox:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
518
+
519
+ /* Freeday — Avatar */
520
+ .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;}
521
+ .fdy-avatar img{width:100%;height:100%;object-fit:cover;}
522
+ .fdy-avatar--sm{width:2rem;height:2rem;font-size:var(--text-xs);}
523
+ .fdy-avatar--lg{width:3.5rem;height:3.5rem;font-size:var(--text-lg);}
524
+ .fdy-avatar-group{display:inline-flex;}
525
+ .fdy-avatar-group .fdy-avatar{border:2px solid var(--color-surface);margin-left:calc(var(--space-2)*-1);}
526
+ .fdy-avatar-group .fdy-avatar:first-child{margin-left:0;}
527
+
528
+ /* Freeday — Badge */
529
+ .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);}
530
+ .fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
531
+ .fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
532
+ .fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
533
+ .fdy-badge--info{color:var(--color-info-strong);background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
534
+ .fdy-badge--outline{background:transparent;border-color:var(--color-border-strong);color:var(--color-text-muted);box-shadow:none;}
535
+
536
+ /* Overlay badge — anchors a small count/dot/icon badge to a corner of any element
537
+ * (icon, button, text). Wrap the content in .fdy-badge-wrap; add .fdy-badge-ov as a
538
+ * sibling. Default is a solid neutral pill; colour + dot + position via modifiers. */
539
+ .fdy-badge-wrap{position:relative;display:inline-flex;vertical-align:middle;}
540
+ .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);}
541
+ .fdy-badge-ov svg{display:block;width:.75rem;height:.75rem;}
542
+ .fdy-badge-ov--dot{min-width:0;width:.75rem;height:.75rem;padding:0;}
543
+ /* Solid colours safe for count/text (on-* tokens, AA in light & dark) */
544
+ .fdy-badge-ov--primary{background:var(--color-primary);color:var(--color-on-primary);}
545
+ .fdy-badge-ov--danger{background:var(--color-danger-btn);color:var(--color-on-danger);}
546
+ /* Dot-oriented accents (for dots — plain text on these is not guaranteed AA) */
547
+ .fdy-badge-ov--accent{background:var(--color-accent);}
548
+ .fdy-badge-ov--info{background:var(--color-info);}
549
+ .fdy-badge-ov--success{background:var(--color-success);}
550
+ .fdy-badge-ov--warning{background:var(--color-warning);}
551
+ /* Anchor position */
552
+ .fdy-badge-ov--top-left{right:auto;left:0;transform:translate(-50%,-50%);}
553
+ .fdy-badge-ov--bottom-right{top:auto;bottom:0;transform:translate(50%,50%);}
554
+ .fdy-badge-ov--bottom-left{top:auto;bottom:0;right:auto;left:0;transform:translate(-50%,50%);}
555
+
556
+ /* Freeday — Breadcrumb */
557
+ .fdy-breadcrumb{font-size:var(--text-sm);}
558
+ .fdy-breadcrumb__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);list-style:none;margin:0;padding:0;}
559
+ .fdy-breadcrumb__item{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--color-text-muted);}
560
+ .fdy-breadcrumb__link{color:var(--color-text-muted);text-decoration:none;border-radius:var(--radius-sm);}
561
+ .fdy-breadcrumb__link:hover{color:var(--color-primary-strong);text-decoration:underline;}
562
+ .fdy-breadcrumb__link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
563
+ .fdy-breadcrumb__item[aria-current="page"]{color:var(--color-text);font-weight:var(--weight-medium);}
564
+ .fdy-breadcrumb__sep{color:var(--color-text-subtle);user-select:none;}
565
+
566
+ /* Freeday — Responsive display utilities (pairs with freeday-breakpoint.js).
567
+ * Breakpoint scale (min-width, px): sm 600 · md 960 · lg 1280 · xl 1920.
568
+ * NOTE: media-query breakpoints must be literal — CSS can't read custom properties
569
+ * inside @media, so these px are structural, not stray magic numbers. */
570
+ .fdy-hidden{display:none !important;}
571
+
572
+ /* hide-below-X — hidden when the viewport is narrower than X (content shows at X and up) */
573
+ @media (max-width:599.98px){.fdy-hide-below-sm{display:none !important;}}
574
+ @media (max-width:959.98px){.fdy-hide-below-md{display:none !important;}}
575
+ @media (max-width:1279.98px){.fdy-hide-below-lg{display:none !important;}}
576
+
577
+ /* hide-above-X — hidden when the viewport is X and wider (content shows below X) */
578
+ @media (min-width:600px){.fdy-hide-above-sm{display:none !important;}}
579
+ @media (min-width:960px){.fdy-hide-above-md{display:none !important;}}
580
+ @media (min-width:1280px){.fdy-hide-above-lg{display:none !important;}}
581
+
582
+ /* Freeday — Button */
583
+ .fdy-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
584
+ height:var(--control-h);padding:0 var(--space-4);
585
+ font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-semibold);
586
+ line-height:1;white-space:nowrap;cursor:pointer;text-decoration:none;color:var(--color-on-primary);
587
+ background:linear-gradient(180deg,var(--color-primary),color-mix(in srgb,#000 10%,var(--color-primary)));
588
+ border:var(--bw) solid transparent;border-radius:var(--radius-md);
589
+ box-shadow:0 2px 9px -1px color-mix(in srgb,var(--color-primary) 50%,transparent),inset 0 1px 0 rgba(255,255,255,.26);
590
+ transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard);}
591
+ .fdy-btn:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-primary) 60%,transparent),inset 0 1px 0 rgba(255,255,255,.26);}
592
+ .fdy-btn:active{transform:translateY(1px);box-shadow:0 1px 4px -1px color-mix(in srgb,var(--color-primary) 46%,transparent);}
593
+ .fdy-btn:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}
594
+
595
+ .fdy-btn--ghost{background:var(--color-surface);color:var(--color-primary-strong);border-color:var(--color-border-strong);box-shadow:var(--shadow-1);}
596
+ .fdy-btn--ghost:hover{transform:none;background:var(--color-primary-soft);border-color:var(--color-primary-border);box-shadow:var(--shadow-1);}
597
+ .fdy-btn--ghost:active{transform:translateY(1px);}
598
+
599
+ .fdy-btn--danger{background:linear-gradient(180deg,var(--color-danger-btn),color-mix(in srgb,#000 12%,var(--color-danger-btn)));color:var(--color-on-danger);box-shadow:0 2px 9px -1px color-mix(in srgb,var(--color-danger-btn) 46%,transparent),inset 0 1px 0 rgba(255,255,255,.22);}
600
+ .fdy-btn--danger:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-danger-btn) 54%,transparent),inset 0 1px 0 rgba(255,255,255,.22);}
601
+ .fdy-btn--danger:active{transform:translateY(1px);}
602
+
603
+ .fdy-btn--sm{height:calc(var(--control-h) - var(--space-2));padding:0 var(--space-3);font-size:var(--text-xs);border-radius:var(--radius-sm);}
604
+ .fdy-btn--lg{height:calc(var(--control-h) + var(--space-2));padding:0 var(--space-6);font-size:var(--text-base);border-radius:var(--radius-lg);}
605
+
606
+ /* Icon inside a button — scales with the button's font size (works for text+icon & icon-only) */
607
+ .fdy-btn__icon{display:inline-flex;flex:none;}
608
+ .fdy-btn__icon svg{display:block;width:1.15em;height:1.15em;}
609
+
610
+ /* Text button — lowest emphasis (no fill/border), colored label, subtle hover tint */
611
+ .fdy-btn--text{background:none;color:var(--color-primary-strong);border-color:transparent;box-shadow:none;}
612
+ .fdy-btn--text:hover{transform:none;background:var(--color-primary-soft);box-shadow:none;}
613
+ .fdy-btn--text:active{transform:translateY(1px);box-shadow:none;}
614
+
615
+ /* Icon-only — square; combine with --ghost/--text/--sm/--lg. Requires aria-label. */
616
+ .fdy-btn--icon{width:var(--control-h);padding:0;}
617
+ .fdy-btn--icon.fdy-btn--sm{width:calc(var(--control-h) - var(--space-2));}
618
+ .fdy-btn--icon.fdy-btn--lg{width:calc(var(--control-h) + var(--space-2));}
619
+
620
+ /* Button group — segmented, joined borders, rounded only at the ends */
621
+ .fdy-btn-group{display:inline-flex;}
622
+ .fdy-btn-group .fdy-btn{border-radius:0;}
623
+ .fdy-btn-group .fdy-btn:not(:first-child){margin-left:calc(var(--bw) * -1);}
624
+ .fdy-btn-group .fdy-btn:hover,.fdy-btn-group .fdy-btn:focus-visible{z-index:1;}
625
+ .fdy-btn-group .fdy-btn:first-child{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md);}
626
+ .fdy-btn-group .fdy-btn:last-child{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md);}
627
+
628
+ /* FAB — circular elevated action button (icon), optional extended pill with label */
629
+ .fdy-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);width:3.5rem;height:3.5rem;padding:0;border:var(--bw) solid transparent;border-radius:var(--radius-full);cursor:pointer;color:var(--color-on-primary);background:linear-gradient(180deg,var(--color-primary),color-mix(in srgb,#000 10%,var(--color-primary)));box-shadow:var(--shadow-3);transition:transform var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
630
+ .fdy-fab:hover{transform:translateY(-1px);box-shadow:var(--shadow-4);}
631
+ .fdy-fab:active{transform:translateY(1px);}
632
+ .fdy-fab:focus-visible{border-radius:var(--radius-full);}
633
+ .fdy-fab:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}
634
+ .fdy-fab svg{display:block;width:1.5rem;height:1.5rem;}
635
+ .fdy-fab--sm{width:2.5rem;height:2.5rem;}
636
+ .fdy-fab--sm svg{width:1.25rem;height:1.25rem;}
637
+ .fdy-fab--extended{width:auto;padding:0 var(--space-5);font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-semibold);}
638
+ .fdy-fab--danger{background:linear-gradient(180deg,var(--color-danger-btn),color-mix(in srgb,#000 12%,var(--color-danger-btn)));color:var(--color-on-danger);}
639
+ .fdy-fab--accent{background:linear-gradient(180deg,var(--color-accent),color-mix(in srgb,#000 10%,var(--color-accent)));color:var(--color-on-accent);}
640
+
641
+ /* Freeday — Card */
642
+ .fdy-card{background:var(--color-surface);border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-lift);transition:box-shadow var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-standard);}
643
+ .fdy-card--elevated{box-shadow:var(--shadow-lift-hover);}
644
+ .fdy-card--interactive{cursor:pointer;}
645
+ .fdy-card--interactive:hover{box-shadow:var(--shadow-lift-hover);transform:translateY(-3px);}
646
+ .fdy-card__body{padding:var(--space-5);}
647
+ .fdy-card__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);color:var(--color-text);margin:0 0 var(--space-1);}
648
+ .fdy-card__desc{font-size:var(--text-sm);color:var(--color-text-muted);margin:0;line-height:var(--leading-normal);}
649
+ .fdy-card__footer{padding:var(--space-3) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:linear-gradient(180deg,var(--color-surface),var(--color-surface-2));display:flex;gap:var(--space-2);justify-content:flex-end;}
650
+
651
+ /* Freeday — Carousel (scroll-snap track + arrows + dots). Enhanced by freeday-carousel.js. */
652
+ .fdy-carousel{position:relative;}
653
+ .fdy-carousel__viewport{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;border-radius:var(--radius-lg);scrollbar-width:none;-ms-overflow-style:none;}
654
+ .fdy-carousel__viewport::-webkit-scrollbar{display:none;}
655
+ .fdy-carousel__slide{flex:0 0 100%;min-width:0;scroll-snap-align:center;}
656
+ .fdy-carousel__arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border:0;border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-surface) 86%,transparent);color:var(--color-text);box-shadow:var(--shadow-2);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard);}
657
+ .fdy-carousel__arrow:hover{background:var(--color-surface);}
658
+ .fdy-carousel__arrow:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 40%,transparent);}
659
+ .fdy-carousel__arrow:disabled{opacity:.4;cursor:not-allowed;}
660
+ .fdy-carousel__arrow--prev{left:var(--space-3);}
661
+ .fdy-carousel__arrow--next{right:var(--space-3);}
662
+ .fdy-carousel__arrow svg{display:block;width:1.25rem;height:1.25rem;}
663
+ .fdy-carousel__dots{display:flex;justify-content:center;gap:var(--space-2);margin-top:var(--space-3);}
664
+ .fdy-carousel__dot{width:.5rem;height:.5rem;padding:0;border:0;border-radius:var(--radius-full);background:var(--color-border-strong);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),width var(--dur-fast) var(--ease-standard);}
665
+ .fdy-carousel__dot[aria-current="true"]{background:var(--color-primary);width:1.25rem;}
666
+ .fdy-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 40%,transparent);}
667
+ @media (prefers-reduced-motion:reduce){.fdy-carousel__viewport{scroll-behavior:auto;}}
668
+
669
+ /* Freeday — Cascade select (hierarchical drill-down picker).
670
+ * Built by freeday-cascade.js from a [data-fdy-cascade] wrapper whose hidden
671
+ * nested <ul> is the data model: a <li> with a child <ul> is a branch, one
672
+ * without is a selectable leaf. The popover shows one level at a time — branches
673
+ * drill in, a back control ascends, a leaf selects (value = full path).
674
+ * Trigger visual matches the combo / date / time control family. */
675
+ .fdy-cascade{position:relative;display:inline-block;width:100%;max-width:22rem;}
676
+ .fdy-cascade__trigger{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
677
+ .fdy-cascade__trigger:hover{border-color:var(--color-text-muted);}
678
+ .fdy-cascade__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
679
+ .fdy-cascade__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
680
+ .fdy-cascade__trigger:disabled,.fdy-cascade__trigger[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
681
+ .fdy-cascade--error .fdy-cascade__trigger,.fdy-cascade__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
682
+ .fdy-cascade--error .fdy-cascade__trigger:focus-visible,.fdy-cascade--error .fdy-cascade__trigger.is-open,.fdy-cascade__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
683
+ .fdy-cascade__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
684
+ .fdy-cascade__value--placeholder{color:var(--color-text-subtle);}
685
+ .fdy-cascade__trigger::after{content:"";flex:none;width:.5rem;height:.5rem;margin-top:-.15rem;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);}
686
+ .fdy-cascade__trigger.is-open::after{transform:rotate(225deg);margin-top:.1rem;}
687
+
688
+ .fdy-cascade__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:100%;margin:0;padding:var(--space-1);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);}
689
+ .fdy-cascade__panel[hidden]{display:none;}
690
+ .fdy-cascade__panel:focus-visible{outline:none;}
691
+ .fdy-cascade__head{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-1) var(--space-2);margin-bottom:var(--space-1);border-bottom:var(--bw) solid var(--color-border);}
692
+ .fdy-cascade__back{display:inline-flex;align-items:center;justify-content:center;flex:none;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);cursor:pointer;}
693
+ .fdy-cascade__back:hover{background:var(--color-surface-3);color:var(--color-text);}
694
+ .fdy-cascade__back:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
695
+ .fdy-cascade__back[hidden]{display:none;}
696
+ .fdy-cascade__back svg{display:block;width:1rem;height:1rem;}
697
+ .fdy-cascade__crumb{min-width:0;flex:1;font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
698
+ .fdy-cascade__list{margin:0;padding:0;list-style:none;max-height:14rem;overflow-y:auto;}
699
+ .fdy-cascade__opt{display:flex;align-items:center;justify-content:space-between;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;}
700
+ .fdy-cascade__opt:hover,.fdy-cascade__opt.is-active{background:var(--color-surface-3);}
701
+ .fdy-cascade__opt[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
702
+ .fdy-cascade__opt-label{overflow:hidden;text-overflow:ellipsis;}
703
+ .fdy-cascade__opt-arrow{flex:none;width:.45rem;height:.45rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(-45deg);}
704
+ @media (prefers-reduced-motion:no-preference){.fdy-cascade__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
705
+
706
+ /* Freeday — Choose-from-list dialog (searchable master-data picker).
707
+ * Built on .fdy-modal: header + search + scrollable results table + footer.
708
+ * Backs a choose-from-list field (readonly input + .fdy-input-group__btn magnifier). */
709
+ .fdy-modal--cfl{width:min(46rem,calc(100vw - var(--space-8)));}
710
+ .fdy-modal--cfl .fdy-modal__body{padding:0;display:flex;flex-direction:column;min-height:0;overflow:hidden;}
711
+
712
+ /* Search bar — single leading-icon field; Enter/typing filters the results. */
713
+ .fdy-cfl__search{flex:none;padding:var(--space-4) var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
714
+
715
+ /* Results — dense rows, sticky header, its own scroll region. */
716
+ .fdy-cfl__results{overflow:auto;max-height:min(24rem,50vh);}
717
+ .fdy-cfl__results .fdy-table th{position:sticky;top:0;z-index:1;}
718
+ .fdy-cfl__row{cursor:pointer;}
719
+ .fdy-cfl__row:hover{background:var(--color-surface-2);}
720
+ .fdy-cfl__row:focus-visible{outline:none;background:var(--color-primary-soft);box-shadow:inset 2px 0 0 var(--color-primary);}
721
+ .fdy-cfl__row[aria-selected="true"]{background:var(--color-primary-soft);}
722
+ .fdy-cfl__row[aria-selected="true"] td:first-child{font-weight:var(--weight-semibold);}
723
+ .fdy-cfl__check{width:1px;white-space:nowrap;}
724
+ .fdy-cfl__check input{pointer-events:none;}
725
+
726
+ /* Empty result state. */
727
+ .fdy-cfl__empty{padding:var(--space-8) var(--space-5);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm);}
728
+ .fdy-cfl__empty[hidden]{display:none;}
729
+
730
+ /* Footer — selection count (multi) sits left, actions right. */
731
+ .fdy-modal--cfl .fdy-modal__footer{justify-content:space-between;}
732
+ .fdy-cfl__count{font-size:var(--text-sm);color:var(--color-text-muted);}
733
+ .fdy-cfl__actions{display:flex;gap:var(--space-2);}
734
+
735
+ /* Freeday — Charts (zero-dependency CSS/SVG, rendered by freeday-chart.js).
736
+ * Colour comes from --fdy-chart (a token, set inline by the renderer from data-fdy-color). */
737
+
738
+ /* Sparkline / trend line (SVG) */
739
+ .fdy-sparkline{display:inline-block;width:8rem;height:2.25rem;vertical-align:middle;color:var(--fdy-chart,var(--color-primary));}
740
+ .fdy-sparkline svg{display:block;width:100%;height:100%;}
741
+ .fdy-sparkline__area{fill:currentColor;opacity:.14;stroke:none;}
742
+ .fdy-sparkline__line{fill:none;stroke:currentColor;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;}
743
+ .fdy-sparkline__dot{fill:currentColor;}
744
+
745
+ /* Bar chart (flex bars) */
746
+ .fdy-bars{position:relative;display:flex;align-items:flex-end;gap:var(--space-2);height:9rem;color:var(--fdy-chart,var(--color-primary));}
747
+ .fdy-bars__col{flex:1;display:flex;flex-direction:column;align-items:center;min-width:0;height:100%;}
748
+ .fdy-bars__track{flex:1;width:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:var(--space-1);min-height:0;}
749
+ .fdy-bars__val{font-size:var(--text-xs);font-variant-numeric:tabular-nums;color:var(--color-text-muted);}
750
+ .fdy-bars__bar{width:100%;max-width:2.5rem;border-radius:var(--radius-sm) var(--radius-sm) 0 0;background:currentColor;transition:height var(--dur-base) var(--ease-standard),opacity var(--dur-fast) var(--ease-standard);}
751
+ .fdy-bars__label{margin-top:var(--space-1);font-size:var(--text-xs);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
752
+ /* Hover emphasis: dim all bars while the chart is hovered, keep the hovered one lit. */
753
+ @media (hover:hover){.fdy-bars:hover .fdy-bars__bar{opacity:.4;}.fdy-bars__col:hover .fdy-bars__bar{opacity:1;}}
754
+
755
+ /* Interactive tooltip (shared by bar + donut) — Chart.js-style hover readout. */
756
+ .fdy-chart__tip{position:absolute;z-index:5;left:0;top:0;pointer-events:none;transform:translate(-50%,calc(-100% - 8px));background:var(--color-inverse-surface);color:var(--color-inverse-text);font-size:var(--text-xs);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);white-space:nowrap;box-shadow:var(--shadow-2);opacity:0;transition:opacity var(--dur-fast) var(--ease-standard);}
757
+ .fdy-chart__tip.is-visible{opacity:1;}
758
+
759
+ /* Donut (conic-gradient ring + legend) */
760
+ .fdy-donut{display:inline-flex;align-items:center;gap:var(--space-5);flex-wrap:wrap;}
761
+ .fdy-donut__ring{position:relative;width:8rem;height:8rem;border-radius:50%;flex:none;}
762
+ .fdy-donut__ring::after{content:"";position:absolute;inset:24%;border-radius:50%;background:var(--color-surface);}
763
+ .fdy-donut__center{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;}
764
+ .fdy-donut__center b{font-family:var(--font-display);font-size:var(--text-xl);color:var(--color-text);line-height:1;}
765
+ .fdy-donut__center span{font-size:var(--text-xs);color:var(--color-text-muted);}
766
+ /* Donut hit-layer: transparent SVG sectors over the ring for per-slice hover. */
767
+ .fdy-donut__hit{position:absolute;inset:0;z-index:2;width:100%;height:100%;overflow:visible;}
768
+ .fdy-donut__seg{fill:transparent;cursor:pointer;transition:fill var(--dur-fast) var(--ease-standard);}
769
+ @media (hover:hover){.fdy-donut__seg:hover{fill:rgba(255,255,255,.3);}}
770
+ .fdy-chart__legend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-2);}
771
+ .fdy-chart__legend li{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);}
772
+ .fdy-chart__swatch{width:.75rem;height:.75rem;border-radius:var(--radius-xs);flex:none;}
773
+ /* Horizontal legend for cartesian charts (legend sits above the plot). */
774
+ .fdy-chart__legend--row{flex-direction:row;flex-wrap:wrap;gap:var(--space-2) var(--space-4);}
775
+
776
+ /* Cartesian charts (line / area / multi-series & stacked bar) — SVG with themed axes.
777
+ * Axis colour comes from --chart-grid / --chart-tick (both theme-aware); series colours are
778
+ * set inline by the renderer from --chart-1..8, so the whole chart recolours on data-theme. */
779
+ .fdy-chart-xy{position:relative;display:flex;flex-direction:column;gap:var(--space-3);width:100%;}
780
+ .fdy-chart-xy__plot{width:100%;aspect-ratio:16/9;min-height:8rem;}
781
+ .fdy-chart-xy__plot svg{display:block;width:100%;height:100%;overflow:visible;}
782
+ .fdy-chart-xy__grid{stroke:var(--chart-grid);stroke-width:1;shape-rendering:crispEdges;}
783
+ .fdy-chart-xy__tick{fill:var(--chart-tick);font-family:var(--font-mono);font-size:9px;}
784
+ .fdy-chart-xy__xlabel{fill:var(--chart-tick);font-family:var(--font-body);font-size:9px;}
785
+ .fdy-chart-xy__line{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke;}
786
+ .fdy-chart-xy__area{stroke:none;opacity:.14;}
787
+ .fdy-chart-xy__dot{stroke:var(--color-surface);stroke-width:1;}
788
+ .fdy-chart-xy__bar{transition:opacity var(--dur-fast) var(--ease-standard);}
789
+ .fdy-chart-xy__band{fill:transparent;cursor:pointer;}
790
+
791
+ /* Freeday — Chip (tag / removable filter) */
792
+ .fdy-chip{display:inline-flex;align-items:center;gap:var(--space-2);height:1.75rem;padding:0 var(--space-3);border-radius:var(--radius-full);font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--color-text);background:var(--color-surface-3);border:var(--bw) solid var(--color-border);}
793
+ .fdy-chip--primary{color:var(--color-primary-strong);background:var(--color-primary-soft);border-color:color-mix(in srgb,var(--color-primary) 22%,transparent);}
794
+ .fdy-chip__remove{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-right:calc(var(--space-1)*-1);border:0;padding:0;border-radius:var(--radius-full);background:transparent;color:currentColor;opacity:.6;cursor:pointer;font-size:var(--text-sm);line-height:1;}
795
+ .fdy-chip__remove:hover{opacity:1;background:color-mix(in srgb,currentColor 16%,transparent);}
796
+ .fdy-chip__remove:focus-visible{outline:none;opacity:1;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
797
+ /* Group wrapper for a row of chips (choice / filter). */
798
+ .fdy-chips{display:flex;flex-wrap:wrap;gap:var(--space-2);}
799
+ /* Interactive chips: choice (toggle) + filter (toggle with a check when on).
800
+ * Rendered as <button aria-pressed> and enhanced by freeday-chip.js. */
801
+ .fdy-chip--choice,.fdy-chip--filter{cursor:pointer;font-family:inherit;background:var(--color-surface);border-color:var(--color-border);transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
802
+ .fdy-chip--choice:hover,.fdy-chip--filter:hover{background:var(--color-surface-3);border-color:var(--color-text-subtle);}
803
+ .fdy-chip--choice:focus-visible,.fdy-chip--filter:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
804
+ .fdy-chip--choice[aria-pressed="true"],.fdy-chip--filter[aria-pressed="true"]{color:var(--color-primary-strong);background:var(--color-primary-soft);border-color:color-mix(in srgb,var(--color-primary) 40%,transparent);}
805
+ .fdy-chip--choice:disabled,.fdy-chip--filter:disabled,.fdy-chip--choice[aria-disabled="true"],.fdy-chip--filter[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
806
+ .fdy-chip__check{display:none;flex:none;width:.85rem;height:.85rem;margin-left:calc(var(--space-1)*-1);}
807
+ .fdy-chip__check svg{display:block;width:100%;height:100%;}
808
+ .fdy-chip--filter[aria-pressed="true"] .fdy-chip__check{display:inline-flex;}
809
+
810
+ /* Freeday — Combobox (custom styled select, WAI-ARIA APG select-only) */
811
+ .fdy-combo{position:relative;display:block;max-width:22rem;}
812
+ .fdy-combo__button{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
813
+ .fdy-combo__button:hover{border-color:var(--color-text-muted);}
814
+ .fdy-combo__button:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
815
+ .fdy-combo__button.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
816
+ .fdy-combo__button:disabled,.fdy-combo__button[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
817
+ .fdy-combo--error .fdy-combo__button,.fdy-combo__button[aria-invalid="true"]{border-color:var(--color-danger);}
818
+ .fdy-combo--error .fdy-combo__button:focus-visible,.fdy-combo--error .fdy-combo__button.is-open,.fdy-combo__button[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
819
+ .fdy-combo__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
820
+ .fdy-combo__value--placeholder{color:var(--color-text-subtle);}
821
+ .fdy-combo__button::after{content:"";flex:none;width:.5rem;height:.5rem;margin-top:-.15rem;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);}
822
+ .fdy-combo__button.is-open::after{transform:rotate(225deg);margin-top:.1rem;}
823
+ /* Icon variants: --no-icon drops the default caret; add a .fdy-combo__icon element
824
+ * inside the button (with --no-icon) to supply a custom trailing icon. */
825
+ .fdy-combo--no-icon .fdy-combo__button::after{display:none;}
826
+ .fdy-combo__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
827
+ .fdy-combo__icon svg{display:block;width:1.05rem;height:1.05rem;}
828
+ .fdy-combo__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);}
829
+ .fdy-combo__listbox[hidden]{display:none;}
830
+ .fdy-combo__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;}
831
+ .fdy-combo__option.is-highlighted{background:var(--color-surface-3);}
832
+ .fdy-combo__option[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
833
+ .fdy-combo__option.is-highlighted[aria-selected="true"]{box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 55%,transparent);}
834
+ .fdy-combo__check{display:inline-flex;justify-content:center;width:var(--space-4);flex:none;font-weight:var(--weight-bold);color:var(--color-primary);}
835
+ @media (prefers-reduced-motion:no-preference){.fdy-combo__listbox:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
836
+ @keyframes fdy-combo-in{from{opacity:0;transform:translateY(-4px);}to{opacity:1;transform:none;}}
837
+
838
+ /* Freeday — Date picker (input-styled trigger + calendar popover).
839
+ * Built by freeday-datepicker.js from an empty [data-fdy-datepicker] wrapper. */
840
+ .fdy-datepicker{position:relative;display:inline-block;width:100%;max-width:14rem;}
841
+ .fdy-datepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
842
+ .fdy-datepicker__trigger:hover{border-color:var(--color-text-muted);}
843
+ .fdy-datepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
844
+ .fdy-datepicker__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
845
+ .fdy-datepicker--error .fdy-datepicker__trigger,.fdy-datepicker__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
846
+ .fdy-datepicker--error .fdy-datepicker__trigger:focus-visible,.fdy-datepicker--error .fdy-datepicker__trigger.is-open,.fdy-datepicker__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
847
+ .fdy-datepicker__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
848
+ .fdy-datepicker__value--placeholder{color:var(--color-text-subtle);}
849
+ .fdy-datepicker__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
850
+ .fdy-datepicker__icon svg{display:block;width:1.05rem;height:1.05rem;}
851
+
852
+ .fdy-datepicker__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;padding:var(--space-3);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);}
853
+ .fdy-datepicker__panel[hidden]{display:none;}
854
+
855
+ /* Calendar grid */
856
+ .fdy-cal__head{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-2);}
857
+ .fdy-cal__title{flex:1;text-align:center;font-weight:var(--weight-semibold);font-size:var(--text-sm);color:var(--color-text);text-transform:capitalize;}
858
+ .fdy-cal__nav{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-size:var(--text-lg);line-height:1;cursor:pointer;}
859
+ .fdy-cal__nav:hover{background:var(--color-surface-2);color:var(--color-text);}
860
+ .fdy-cal__nav:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
861
+ .fdy-cal__grid{display:grid;grid-template-columns:repeat(7,2rem);gap:2px;}
862
+ .fdy-cal__dow{display:flex;align-items:center;justify-content:center;height:1.75rem;font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);text-transform:capitalize;}
863
+ .fdy-cal__day{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-size:var(--text-sm);font-variant-numeric:tabular-nums;cursor:pointer;}
864
+ .fdy-cal__day:hover{background:var(--color-surface-2);}
865
+ .fdy-cal__day:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
866
+ .fdy-cal__day.is-outside{color:var(--color-text-subtle);opacity:.55;}
867
+ .fdy-cal__day.is-today{font-weight:var(--weight-bold);box-shadow:inset 0 0 0 1.5px var(--color-border-strong);}
868
+ .fdy-cal__day.in-range{background:var(--color-primary-soft);color:var(--color-primary-strong);border-radius:0;}
869
+ .fdy-cal__day.is-selected{background:var(--color-primary);color:var(--color-on-primary);font-weight:var(--weight-semibold);}
870
+ .fdy-cal__day.is-selected:hover{background:var(--color-primary-hover);}
871
+ .fdy-cal__day:disabled{opacity:.35;cursor:not-allowed;}
872
+ .fdy-cal__day:disabled:hover{background:transparent;}
873
+
874
+ /* Range: two linked pickers */
875
+ /* Responsive: each picker may shrink (min-width:0) & wrap so the range never overflows a
876
+ narrow row/phone; inline-flex still hugs to ~23rem at wider widths (look unchanged). */
877
+ .fdy-daterange{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);}
878
+ .fdy-daterange .fdy-datepicker{flex:0 1 11rem;min-width:0;}
879
+ .fdy-daterange__sep{flex:none;color:var(--color-text-subtle);}
880
+
881
+ @media (prefers-reduced-motion:no-preference){.fdy-datepicker__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
882
+
883
+ /* Freeday — Datetime picker (composed: date picker + time picker → one value).
884
+ * A thin composer (freeday-datetime.js) links a child [data-fdy-datepicker] and
885
+ * [data-fdy-timepicker] and emits a single combined event. Icon variants come from
886
+ * the child pickers (data-fdy-no-icon / <template data-fdy-icon>). */
887
+ .fdy-datetimepicker{display:inline-flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;}
888
+ /* Fixed widths so date + time sit side by side (children default to width:100%). */
889
+ .fdy-datetimepicker .fdy-datepicker{width:12rem;max-width:none;}
890
+ .fdy-datetimepicker .fdy-timepicker{width:8.5rem;max-width:none;}
891
+
892
+ /* Freeday — Description list (key-value detail view) */
893
+ .fdy-dl{display:grid;grid-template-columns:auto 1fr;gap:var(--space-2) var(--space-5);margin:0;}
894
+ .fdy-dl dt{color:var(--color-text-muted);font-size:var(--text-sm);}
895
+ .fdy-dl dd{margin:0;color:var(--color-text);font-size:var(--text-sm);font-weight:var(--weight-medium);}
896
+ .fdy-dl--rows{grid-template-columns:1fr;gap:var(--space-1);}
897
+ .fdy-dl--rows dt{margin-top:var(--space-2);}
898
+
899
+ /* Freeday — Divider */
900
+ .fdy-divider{border:0;border-top:var(--bw) solid var(--color-border);margin:var(--space-4) 0;}
901
+ .fdy-divider--vertical{border-top:0;border-left:var(--bw) solid var(--color-border);margin:0 var(--space-4);align-self:stretch;}
902
+
903
+ /* Freeday — Drawer (temporary side panel on native <dialog>: focus-trap / Esc /
904
+ * backdrop / return-focus are free). Anchors left (default) or right.
905
+ * Enhanced by freeday-drawer.js (open trigger + backdrop-click close). */
906
+ /* display is gated behind [open] so the native <dialog> stays hidden until opened.
907
+ * An unconditional display here would beat the UA `dialog:not([open]){display:none}`
908
+ * rule (author origin wins over user-agent) and leave the drawer visible on load. */
909
+ .fdy-drawer{position:fixed;inset:0 auto 0 0;margin:0;padding:0;height:100vh;max-height:none;width:min(20rem,82vw);flex-direction:column;border:0;background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-4);overflow:hidden;transform:translateX(-100%);transition:transform var(--dur-slow) var(--ease-standard),overlay var(--dur-slow) allow-discrete,display var(--dur-slow) allow-discrete;}
910
+ .fdy-drawer[open]{display:flex;transform:none;}
911
+ .fdy-drawer--right{inset:0 0 0 auto;transform:translateX(100%);}
912
+ .fdy-drawer::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-slow) var(--ease-standard),overlay var(--dur-slow) allow-discrete,display var(--dur-slow) allow-discrete;}
913
+ .fdy-drawer__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
914
+ .fdy-drawer__title{font-family:var(--font-display);font-weight:var(--weight-semibold);font-size:var(--text-lg);color:var(--color-text);margin:0 auto 0 0;}
915
+ .fdy-drawer__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
916
+ .fdy-drawer__close:hover{background:var(--color-surface-2);color:var(--color-text);}
917
+ .fdy-drawer__body{flex:1;min-height:0;overflow:auto;padding:var(--space-4);}
918
+ /* Symmetric enter AND exit on the native <dialog>: @starting-style animates the entry;
919
+ * the overlay/display allow-discrete transitions keep the panel painted through the exit so
920
+ * it slides back out on close (not just in). prefers-reduced-motion is honored by the global
921
+ * duration reset in base.css. Unsupported browsers degrade to an instant open/close. */
922
+ .fdy-drawer[open]::backdrop{opacity:1;}
923
+ @starting-style{
924
+ .fdy-drawer[open]{transform:translateX(-100%);}
925
+ .fdy-drawer--right[open]{transform:translateX(100%);}
926
+ .fdy-drawer[open]::backdrop{opacity:0;}
927
+ }
928
+
929
+ /* Freeday — File upload (drop target + explicit per-file states).
930
+ * Enhanced by freeday-upload.js; states: idle · drag-over · uploading · done · error. */
931
+ .fdy-dropzone{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-6);text-align:center;border:2px dashed var(--color-control-border);border-radius:var(--radius-lg);background:var(--color-surface-2);color:var(--color-text-muted);cursor:pointer;transition:border-color var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
932
+ .fdy-dropzone:hover{border-color:var(--color-text-muted);}
933
+ .fdy-dropzone:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
934
+ .fdy-dropzone.is-dragover{border-color:var(--color-primary);background:var(--color-primary-soft);color:var(--color-primary-strong);}
935
+ .fdy-dropzone__icon{color:var(--color-text-subtle);}
936
+ .fdy-dropzone.is-dragover .fdy-dropzone__icon{color:var(--color-primary);}
937
+ .fdy-dropzone__icon svg{display:block;width:2rem;height:2rem;}
938
+ .fdy-dropzone__title{font-weight:var(--weight-medium);color:var(--color-text);}
939
+ .fdy-dropzone__hint{font-size:var(--text-xs);}
940
+ /* Wide (horizontal) layout — icon beside the copy instead of stacked, for full-width
941
+ * sections. Wrap the title + hint in .fdy-dropzone__text. */
942
+ .fdy-dropzone--row{flex-direction:row;align-items:center;justify-content:center;text-align:left;gap:var(--space-4);}
943
+ .fdy-dropzone__text{display:flex;flex-direction:column;gap:var(--space-1);}
944
+
945
+ /* File rows (list of added/uploaded/rejected files) */
946
+ .fdy-filelist{display:flex;flex-direction:column;gap:var(--space-2);margin-top:var(--space-3);}
947
+ /* Side-by-side rows on wide screens (reflow to one column when narrow). */
948
+ .fdy-filelist--grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));}
949
+ .fdy-file{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3);border:var(--bw) solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);}
950
+ .fdy-file__icon{flex:none;display:inline-flex;color:var(--color-text-muted);}
951
+ .fdy-file__icon svg{display:block;width:1.25rem;height:1.25rem;}
952
+ .fdy-file__meta{flex:1;min-width:0;}
953
+ .fdy-file__name{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
954
+ .fdy-file__sub{font-size:var(--text-xs);color:var(--color-text-muted);}
955
+ .fdy-file__progress{margin-top:var(--space-2);}
956
+ .fdy-file__remove{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-size:var(--text-lg);line-height:1;cursor:pointer;}
957
+ .fdy-file__remove:hover{background:var(--color-surface-2);color:var(--color-text);}
958
+ .fdy-file__remove:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
959
+ .fdy-file--success .fdy-file__icon{color:var(--color-success);}
960
+ .fdy-file--error{border-color:color-mix(in srgb,var(--color-danger) 40%,var(--color-border));}
961
+ .fdy-file--error .fdy-file__icon{color:var(--color-danger);}
962
+ .fdy-file--error .fdy-file__sub{color:var(--color-danger-strong);}
963
+
964
+ /* Freeday — Filter bar (a consistent row of filters: search + selects + actions).
965
+ * Solves the "ragged filter row": apps improvised flex rows with ad-hoc
966
+ * flex/min-width, so grow fields ballooned while selects stayed tiny and no two
967
+ * screens matched. Here every field snaps to a shared width rhythm; one field may
968
+ * --w-grow to absorb the slack; trailing actions align to the controls. Fields are
969
+ * the standard .fdy-field (label above control); wraps gracefully on narrow screens. */
970
+ .fdy-filterbar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-3) var(--space-4);}
971
+ /* Fields are direct children. Drop the standalone field's 22rem cap; default to the
972
+ * medium column width with no unbounded growth (that's what caused the raggedness). */
973
+ .fdy-filterbar>.fdy-field{max-width:none;flex:0 0 auto;width:12rem;}
974
+ /* Controls fill their field's column (drop the standalone input-group/combo caps). */
975
+ .fdy-filterbar>.fdy-field .fdy-input-group,.fdy-filterbar>.fdy-field .fdy-combo{max-width:none;width:100%;}
976
+ /* Column-width rhythm — pick one per field so bars across the app line up. */
977
+ .fdy-filterbar>.fdy-field--w-sm{width:9rem;}
978
+ .fdy-filterbar>.fdy-field--w-lg{width:15rem;}
979
+ .fdy-filterbar>.fdy-field--w-xl{width:18rem;}
980
+ /* One growing field (usually the search) absorbs the remaining width. */
981
+ .fdy-filterbar>.fdy-field--w-grow{flex:1 1 16rem;width:auto;min-width:12rem;}
982
+ /* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline. */
983
+ .fdy-filterbar__actions{display:flex;align-items:center;gap:var(--space-2);margin-left:auto;}
984
+ /* Stack on narrow screens so nothing overflows the row. */
985
+ @media (max-width:640px){
986
+ .fdy-filterbar>.fdy-field,.fdy-filterbar>.fdy-field--w-sm,.fdy-filterbar>.fdy-field--w-lg,.fdy-filterbar>.fdy-field--w-xl,.fdy-filterbar>.fdy-field--w-grow{width:100%;flex:1 1 100%;}
987
+ .fdy-filterbar__actions{width:100%;margin-left:0;}
988
+ }
989
+
990
+ /* Freeday — Form grid (document/header fields laid out in aligned columns).
991
+ * The two-dimensional counterpart to the single-column .fdy-field stack and the
992
+ * one-row .fdy-filterbar: related fields sit in columns that reflow to one on narrow
993
+ * screens. Fields are the standard .fdy-field; a field with --full spans the whole row
994
+ * (e.g. an address or note). Zero JS — pure layout over .fdy-field. */
995
+ .fdy-form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--space-4) var(--space-5);}
996
+ .fdy-form-grid>.fdy-field{max-width:none;}
997
+ .fdy-form-grid>.fdy-field--full{grid-column:1/-1;}
998
+
999
+ /* Freeday — Input group (prefix/suffix addons, e.g. Rp / % / icon) */
1000
+ .fdy-input-group{display:flex;align-items:stretch;max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1001
+ .fdy-input-group:hover{border-color:var(--color-text-muted);}
1002
+ .fdy-input-group:focus-within{border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1003
+ .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:calc(var(--control-h) - 3px);}
1004
+ .fdy-input-group .fdy-input:focus{box-shadow:none;}
1005
+ .fdy-input-group__addon{display:inline-flex;align-items:center;padding:0 var(--space-3);background:var(--color-surface-2);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;border-right:var(--bw) solid var(--color-border);}
1006
+ .fdy-input-group__addon:last-child{border-right:0;border-left:var(--bw) solid var(--color-border);}
1007
+ /* Borderless leading icon (e.g. search magnifier) — self-contained like __btn so it
1008
+ centers standalone (no base .fdy-input-group__addon required). */
1009
+ .fdy-input-group__addon--icon{display:inline-flex;align-items:center;background:transparent;border:0;padding:0 0 0 var(--space-3);color:var(--color-text-subtle);}
1010
+ .fdy-input-group__addon--icon svg{display:block;width:1rem;height:1rem;}
1011
+ /* The leading icon already provides the left inset — don't let the input add its full left padding on top. */
1012
+ .fdy-input-group__addon--icon + .fdy-input{padding-left:var(--space-2);}
1013
+ /* Trailing action button (e.g. choose-from-list magnifier) — a real, focusable control. */
1014
+ .fdy-input-group__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;width:var(--control-h);align-self:stretch;border:0;border-left:var(--bw) solid var(--color-border);background:var(--color-surface-2);color:var(--color-text-muted);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
1015
+ .fdy-input-group__btn:hover{background:var(--color-surface-3);color:var(--color-text);}
1016
+ .fdy-input-group__btn:focus-visible{outline:none;color:var(--color-text);box-shadow:inset 0 0 0 2px var(--color-primary);}
1017
+ .fdy-input-group__btn svg{display:block;width:1.1rem;height:1.1rem;}
1018
+ /* Error state must win over the neutralizing rules above — promote to the wrapper. */
1019
+ .fdy-input-group:has(.fdy-input--error),.fdy-input-group:has(.fdy-combo--error),.fdy-input-group:has([aria-invalid="true"]){border-color:var(--color-danger);}
1020
+ .fdy-input-group:has(.fdy-input--error):focus-within,.fdy-input-group:has(.fdy-combo--error):focus-within,.fdy-input-group:has([aria-invalid="true"]):focus-within{border-color:var(--color-danger);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
1021
+
1022
+ /* Freeday — Field & Input */
1023
+ .fdy-field{display:flex;flex-direction:column;gap:var(--space-2);max-width:22rem;}
1024
+ .fdy-label{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);}
1025
+ .fdy-input,.fdy-textarea{width:100%;height:var(--control-h);padding:0 var(--space-3);font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1026
+ .fdy-input::placeholder,.fdy-textarea::placeholder{color:var(--color-text-subtle);}
1027
+ .fdy-textarea{height:auto;min-height:5.5rem;padding:var(--space-3);line-height:var(--leading-normal);resize:vertical;}
1028
+ .fdy-input:hover,.fdy-textarea:hover{border-color:var(--color-text-muted);}
1029
+ .fdy-input:focus,.fdy-textarea:focus{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1030
+ .fdy-input:disabled,.fdy-textarea:disabled,.fdy-input[aria-disabled="true"],.fdy-textarea[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
1031
+ .fdy-input--error,.fdy-input[aria-invalid="true"],.fdy-textarea[aria-invalid="true"]{border-color:var(--color-danger);}
1032
+ .fdy-input--error:focus,.fdy-input[aria-invalid="true"]:focus,.fdy-textarea[aria-invalid="true"]:focus{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
1033
+ .fdy-help{font-size:var(--text-xs);color:var(--color-text-muted);}
1034
+ .fdy-help--error{color:var(--color-danger);}
1035
+
1036
+ /* Freeday — Keyboard key */
1037
+ .fdy-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;height:1.5rem;padding:0 var(--space-2);font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text);background:var(--color-surface-2);border:var(--bw) solid var(--color-border-strong);border-bottom-width:2px;border-radius:var(--radius-sm);}
1038
+
1039
+ /* Freeday — Menu (action popup) + Split button. Enhanced by freeday-menu.js. */
1040
+ .fdy-menu-wrap{position:relative;display:inline-flex;}
1041
+ .fdy-menu{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:11rem;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);}
1042
+ .fdy-menu[hidden]{display:none;}
1043
+ .fdy-menu--end{left:auto;right:0;}
1044
+ .fdy-menu__item{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border:0;background:transparent;border-radius:var(--radius-sm);font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);text-align:left;cursor:pointer;white-space:nowrap;}
1045
+ .fdy-menu__item:hover,.fdy-menu__item.is-highlighted{background:var(--color-surface-3);}
1046
+ .fdy-menu__item:focus-visible{outline:none;background:var(--color-surface-3);}
1047
+ .fdy-menu__item:disabled{opacity:.5;cursor:not-allowed;background:transparent;}
1048
+ .fdy-menu__item--danger{color:var(--color-danger-strong);}
1049
+ .fdy-menu__item svg{display:block;width:1rem;height:1rem;flex:none;}
1050
+ .fdy-menu__sep{height:0;margin:var(--space-1) 0;border:0;border-top:var(--bw) solid var(--color-border-muted);}
1051
+ @media (prefers-reduced-motion:no-preference){.fdy-menu:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
1052
+
1053
+ /* Split button — main action + attached menu toggle (caret) */
1054
+ .fdy-btn-split{position:relative;display:inline-flex;border-radius:var(--radius-md);transition:transform var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1055
+ /* One control: the two halves must stay coplanar. Neutralize each segment's own
1056
+ lift + drop-shadow (they would misalign the seam / glow a single half); the
1057
+ split lifts and casts its elevation as a single unit instead. */
1058
+ .fdy-btn-split > .fdy-btn{transform:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.26);}
1059
+ .fdy-btn-split > .fdy-btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0;}
1060
+ .fdy-btn-split__toggle{padding:0 var(--space-2);margin-left:calc(var(--bw) * -1);border-top-left-radius:0;border-bottom-left-radius:0;}
1061
+ /* Hairline divider between the halves (outranks the segment rule above). */
1062
+ .fdy-btn-split > .fdy-btn-split__toggle{box-shadow:inset 0 1px 0 rgba(255,255,255,.26),inset 1px 0 0 rgba(0,0,0,.16);}
1063
+ .fdy-btn-split:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-primary) 55%,transparent);}
1064
+ .fdy-btn-split:active{transform:translateY(1px);box-shadow:0 1px 4px -1px color-mix(in srgb,var(--color-primary) 46%,transparent);}
1065
+ .fdy-btn-split__toggle:hover,.fdy-btn-split__toggle:focus-visible{z-index:1;}
1066
+ .fdy-btn-split__toggle svg{display:block;width:1rem;height:1rem;}
1067
+
1068
+ /* Freeday — Modal (native <dialog>) */
1069
+ .fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
1070
+ .fdy-modal--sm{width:min(24rem,calc(100vw - var(--space-8)));}
1071
+ .fdy-modal--md{width:min(32rem,calc(100vw - var(--space-8)));}
1072
+ .fdy-modal--lg{width:min(48rem,calc(100vw - var(--space-8)));}
1073
+ .fdy-modal--wide{width:min(60rem,calc(100vw - var(--space-8)));}
1074
+ .fdy-modal::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-base) var(--ease-standard),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
1075
+ .fdy-modal__header{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
1076
+ .fdy-modal__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;}
1077
+ .fdy-modal__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
1078
+ .fdy-modal__close:hover{background:var(--color-surface-2);color:var(--color-text);}
1079
+ .fdy-modal__body{padding:var(--space-5);overflow:auto;}
1080
+ .fdy-modal__footer{display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
1081
+ /* Symmetric enter AND exit (fade + rise + subtle scale) on the native <dialog>. @starting-style
1082
+ * animates the entry; overlay/display allow-discrete keep it painted through the exit so it
1083
+ * animates out on close too. Reduced motion honored by the global duration reset in base.css. */
1084
+ .fdy-modal[open]{opacity:1;transform:none;}
1085
+ .fdy-modal[open]::backdrop{opacity:1;}
1086
+ @starting-style{
1087
+ .fdy-modal[open]{opacity:0;transform:translateY(8px) scale(.98);}
1088
+ .fdy-modal[open]::backdrop{opacity:0;}
1089
+ }
1090
+
1091
+ /* Freeday — Pagination */
1092
+ .fdy-pagination__list{display:flex;align-items:center;gap:var(--space-1);list-style:none;margin:0;padding:0;}
1093
+ .fdy-pagination__link{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;padding:0 var(--space-2);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);background:transparent;border:var(--bw) solid transparent;text-decoration:none;cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
1094
+ .fdy-pagination__link:hover{background:var(--color-surface-2);border-color:var(--color-border);}
1095
+ .fdy-pagination__link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1096
+ .fdy-pagination__link[aria-current="page"]{background:var(--color-primary);color:var(--color-on-primary);}
1097
+ .fdy-pagination__link[aria-disabled="true"],.fdy-pagination__link:disabled{opacity:.5;cursor:not-allowed;pointer-events:none;}
1098
+ .fdy-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;color:var(--color-text-subtle);}
1099
+
1100
+ /* Freeday — Progress */
1101
+ .fdy-progress{height:.5rem;border-radius:var(--radius-full);background:var(--color-surface-3);overflow:hidden;}
1102
+ .fdy-progress__bar{height:100%;border-radius:inherit;background:var(--color-primary);transition:width var(--dur-base) var(--ease-standard);}
1103
+ .fdy-progress--indeterminate{position:relative;}
1104
+ .fdy-progress--indeterminate .fdy-progress__bar{width:40%;animation:fdy-progress-indet 1.2s var(--ease-standard) infinite;}
1105
+ @keyframes fdy-progress-indet{0%{margin-left:-40%;}100%{margin-left:100%;}}
1106
+ @media (prefers-reduced-motion:reduce){.fdy-progress--indeterminate .fdy-progress__bar{animation:none;width:100%;opacity:.5;}}
1107
+
1108
+ /* Freeday — Rating (star rating). Interactive = native radio group (arrow keys, form-assoc);
1109
+ * filled vs empty differ by fill-vs-outline (not colour alone). Enhanced by freeday-rating.js. */
1110
+ .fdy-rating{display:inline-flex;gap:var(--space-1);}
1111
+ .fdy-rating__star{display:inline-flex;line-height:0;cursor:pointer;}
1112
+ .fdy-rating__star input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
1113
+ .fdy-rating__star svg{width:1.5rem;height:1.5rem;fill:none;stroke:var(--color-border-strong);stroke-width:1.5;transition:fill var(--dur-fast) var(--ease-standard),stroke var(--dur-fast) var(--ease-standard);}
1114
+ .fdy-rating__star.is-filled svg{fill:var(--color-warning);stroke:var(--color-warning);}
1115
+ .fdy-rating__star input:focus-visible + svg{outline:2px solid var(--color-primary);outline-offset:2px;border-radius:var(--radius-xs);}
1116
+ .fdy-rating--readonly .fdy-rating__star{cursor:default;}
1117
+ .fdy-rating--sm .fdy-rating__star svg{width:1.1rem;height:1.1rem;}
1118
+
1119
+ /* Freeday — Selection controls */
1120
+ .fdy-check,.fdy-radio,.fdy-switch{display:inline-flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;}
1121
+ .fdy-check input,.fdy-radio input{appearance:none;-webkit-appearance:none;width:var(--control-box);height:var(--control-box);margin:0;border:1.5px solid var(--color-control-border);background:var(--color-surface);box-shadow:inset 0 1px 2px var(--color-shadow-inset);cursor:pointer;display:grid;place-content:center;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
1122
+ .fdy-check input{border-radius:var(--radius-sm);}
1123
+ .fdy-radio input{border-radius:50%;}
1124
+ .fdy-check input::before{content:"";width:.62rem;height:.62rem;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%);}
1125
+ .fdy-radio input::before{content:"";width:.55rem;height:.55rem;border-radius:50%;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);}
1126
+ .fdy-check input:checked,.fdy-radio input:checked{background:var(--color-primary);border-color:var(--color-primary);}
1127
+ .fdy-check input:checked::before,.fdy-radio input:checked::before{transform:scale(1);}
1128
+ .fdy-check input:focus-visible,.fdy-radio input:focus-visible,.fdy-switch input:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1129
+ .fdy-check input:disabled,.fdy-radio input:disabled,.fdy-switch input:disabled{opacity:.5;cursor:not-allowed;}
1130
+ .fdy-check:has(input:disabled),.fdy-radio:has(input:disabled),.fdy-switch:has(input:disabled){cursor:not-allowed;}
1131
+ .fdy-switch input{appearance:none;-webkit-appearance:none;position:relative;width:var(--control-switch-w);height:var(--control-switch-h);margin:0;border-radius:var(--radius-full);background:var(--color-control-border);cursor:pointer;transition:background var(--dur-base) var(--ease-standard);}
1132
+ .fdy-switch input::before{content:"";position:absolute;top:2px;left:2px;width:calc(var(--control-switch-h) - 4px);height:calc(var(--control-switch-h) - 4px);border-radius:50%;background:var(--color-switch-thumb);box-shadow:var(--shadow-1);transition:transform var(--dur-base) var(--ease-spring);}
1133
+ .fdy-switch input:checked{background:var(--color-primary);}
1134
+ .fdy-switch input:checked::before{transform:translateX(calc(var(--control-switch-w) - var(--control-switch-h)));}
1135
+
1136
+ /* Standalone checkbox (e.g. table row/select-all) — supports :indeterminate */
1137
+ .fdy-checkbox{appearance:none;-webkit-appearance:none;width:var(--control-box);height:var(--control-box);margin:0;border:1.5px solid var(--color-control-border);border-radius:var(--radius-sm);background:var(--color-surface);box-shadow:inset 0 1px 2px var(--color-shadow-inset);cursor:pointer;display:grid;place-content:center;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
1138
+ .fdy-checkbox::before{content:"";width:.62rem;height:.62rem;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%);}
1139
+ .fdy-checkbox:checked,.fdy-checkbox:indeterminate{background:var(--color-primary);border-color:var(--color-primary);}
1140
+ .fdy-checkbox:checked::before{transform:scale(1);}
1141
+ .fdy-checkbox:indeterminate::before{width:.6rem;height:2px;transform:scale(1);clip-path:none;box-shadow:none;background:var(--color-on-primary);}
1142
+ .fdy-checkbox:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1143
+ .fdy-checkbox:disabled{opacity:.5;cursor:not-allowed;}
1144
+
1145
+ /* Freeday — Skeleton */
1146
+ .fdy-skeleton{display:block;border-radius:var(--radius-sm);background:var(--color-surface-3);background-image:linear-gradient(90deg,transparent,color-mix(in srgb,var(--color-surface) 60%,transparent),transparent);background-size:200% 100%;background-repeat:no-repeat;animation:fdy-skeleton 1.4s ease-in-out infinite;}
1147
+ .fdy-skeleton--text{height:.8rem;margin:.3rem 0;}
1148
+ .fdy-skeleton--title{height:1.2rem;width:40%;}
1149
+ .fdy-skeleton--circle{border-radius:var(--radius-full);}
1150
+ @keyframes fdy-skeleton{to{background-position:-200% 0;}}
1151
+ @media (prefers-reduced-motion:reduce){.fdy-skeleton{animation:none;}}
1152
+
1153
+ /* Freeday — Slider (native <input type="range"> themed via accent-color: keeps native
1154
+ * keyboard + ARIA, filled track and thumb come free). Optional value output + scale.
1155
+ * freeday-slider.js just mirrors the value into an <output for="…">. */
1156
+ .fdy-slider{width:100%;max-width:22rem;height:1.5rem;accent-color:var(--color-primary);cursor:pointer;}
1157
+ .fdy-slider:disabled{cursor:not-allowed;opacity:.6;}
1158
+ .fdy-slider--accent{accent-color:var(--color-accent);}
1159
+ .fdy-slider--danger{accent-color:var(--color-danger);}
1160
+
1161
+ .fdy-slider-field{display:flex;flex-direction:column;gap:var(--space-2);max-width:22rem;}
1162
+ .fdy-slider-field__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);}
1163
+ .fdy-slider__value{font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-primary-strong);font-variant-numeric:tabular-nums;}
1164
+ .fdy-slider__scale{display:flex;justify-content:space-between;font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums;}
1165
+
1166
+ /* Freeday — Spinner */
1167
+ .fdy-spinner{display:inline-block;width:1.5rem;height:1.5rem;border:2.5px solid var(--color-border-strong);border-top-color:var(--color-primary);border-radius:var(--radius-full);animation:fdy-spin .7s linear infinite;}
1168
+ .fdy-spinner--sm{width:1rem;height:1rem;border-width:2px;}
1169
+ .fdy-spinner--lg{width:2.5rem;height:2.5rem;border-width:3px;}
1170
+ @keyframes fdy-spin{to{transform:rotate(360deg);}}
1171
+ @media (prefers-reduced-motion:reduce){.fdy-spinner{animation-duration:2s;}}
1172
+
1173
+ /* Freeday — States (empty / loading / error placeholders) */
1174
+ .fdy-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-2);padding:var(--space-10) var(--space-6);}
1175
+ .fdy-state__icon{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;color:var(--color-text-subtle);}
1176
+ .fdy-state__icon svg{width:100%;height:100%;}
1177
+ .fdy-state__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);}
1178
+ .fdy-state__text{font-size:var(--text-sm);color:var(--color-text-muted);max-width:24rem;line-height:var(--leading-normal);}
1179
+ .fdy-state__actions{margin-top:var(--space-2);display:flex;gap:var(--space-2);flex-wrap:wrap;justify-content:center;}
1180
+ .fdy-state--danger .fdy-state__icon{color:var(--color-danger-strong);}
1181
+
1182
+ /* Freeday — Stepper / Wizard (progress header + optional panels).
1183
+ * Enhanced by freeday-stepper.js for prev/next navigation. */
1184
+ .fdy-stepper{display:flex;list-style:none;margin:0;padding:0;}
1185
+ .fdy-step{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;}
1186
+ /* connector from the previous marker's centre to this one (behind the markers) */
1187
+ .fdy-step:not(:first-child)::before{content:"";position:absolute;top:.875rem;left:-50%;width:100%;height:2px;transform:translateY(-50%);background:var(--color-border-strong);z-index:0;}
1188
+ .fdy-step.is-active::before,.fdy-step.is-complete::before{background:var(--color-primary);}
1189
+ .fdy-step__btn{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:0 var(--space-2);background:none;border:0;font:inherit;color:inherit;cursor:pointer;max-width:100%;}
1190
+ .fdy-step__btn:disabled{cursor:default;}
1191
+ .fdy-step__marker{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--radius-full);background:var(--color-surface);border:2px solid var(--color-border-strong);color:var(--color-text-muted);font-size:var(--text-sm);font-weight:var(--weight-semibold);font-variant-numeric:tabular-nums;}
1192
+ .fdy-step__marker svg{display:block;width:1rem;height:1rem;}
1193
+ .fdy-step.is-active .fdy-step__marker{border-color:var(--color-primary);background:var(--color-primary-soft);color:var(--color-primary-strong);}
1194
+ .fdy-step.is-complete .fdy-step__marker{border-color:var(--color-primary);background:var(--color-primary);color:var(--color-on-primary);}
1195
+ .fdy-step.is-error .fdy-step__marker{border-color:var(--color-danger);background:var(--color-danger-btn);color:var(--color-on-danger);}
1196
+ .fdy-step__label{font-size:var(--text-sm);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
1197
+ .fdy-step.is-active .fdy-step__label{color:var(--color-text);font-weight:var(--weight-semibold);}
1198
+ .fdy-step__btn:focus-visible{outline:none;}
1199
+ .fdy-step__btn:focus-visible .fdy-step__marker{box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 30%,transparent);}
1200
+
1201
+ .fdy-step-panels{margin-top:var(--space-5);}
1202
+ .fdy-step-nav{display:flex;justify-content:space-between;gap:var(--space-2);margin-top:var(--space-5);}
1203
+
1204
+ /* Freeday — Table */
1205
+ .fdy-table-wrap{overflow-x:auto;border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);background:var(--color-surface);}
1206
+ .fdy-table{width:100%;border-collapse:collapse;font-size:var(--text-sm);}
1207
+ .fdy-table caption{text-align:left;padding:var(--space-3) var(--space-4);font-weight:var(--weight-semibold);color:var(--color-text);}
1208
+ .fdy-table th{text-align:left;padding:var(--space-3) var(--space-4);font-size:var(--text-xs);font-weight:var(--weight-semibold);text-transform:uppercase;letter-spacing:var(--tracking-wide);color:var(--color-text-muted);background:var(--color-surface-2);border-bottom:var(--bw) solid var(--color-border);white-space:nowrap;}
1209
+ .fdy-table td{padding:var(--space-3) var(--space-4);border-bottom:var(--bw) solid var(--color-border-muted);color:var(--color-text);}
1210
+ .fdy-table tbody tr:last-child td{border-bottom:0;}
1211
+ .fdy-table tbody tr{transition:background-color var(--dur-fast) var(--ease-standard);}
1212
+ .fdy-table tbody tr:hover{background:var(--color-surface-2);}
1213
+ .fdy-table__num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-mono);}
1214
+ .fdy-table th[aria-sort]{cursor:pointer;}
1215
+ .fdy-table th[aria-sort="ascending"]::after{content:" ↑";color:var(--color-primary);}
1216
+ .fdy-table th[aria-sort="descending"]::after{content:" ↓";color:var(--color-primary);}
1217
+
1218
+ /* Sortable header button (accessible click target inside th) */
1219
+ .fdy-table__sortbtn{appearance:none;border:0;background:transparent;font:inherit;color:inherit;text-transform:inherit;letter-spacing:inherit;font-weight:inherit;cursor:pointer;padding:0;}
1220
+ .fdy-table__sortbtn:hover{color:var(--color-text);}
1221
+ .fdy-table__sortbtn:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1222
+
1223
+ /* Selection column + selected row */
1224
+ .fdy-table__selcol{width:1px;white-space:nowrap;}
1225
+ .fdy-table tbody tr[aria-selected="true"],.fdy-table tbody tr[aria-selected="true"]:hover{background:var(--color-primary-soft);}
1226
+
1227
+ /* Data-table shell (toolbar + scroll + footer stay put while the table scrolls) */
1228
+ .fdy-datatable{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);background:var(--color-surface);overflow:hidden;}
1229
+ .fdy-table-scroll{overflow-x:auto;}
1230
+ .fdy-table-toolbar{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-4);border-bottom:var(--bw) solid var(--color-border);}
1231
+ .fdy-table-toolbar__search{max-width:18rem;}
1232
+ .fdy-table-toolbar__spacer{flex:1;}
1233
+ .fdy-table-toolbar__count{font-size:var(--text-sm);color:var(--color-text-muted);white-space:nowrap;}
1234
+ .fdy-table-footer{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-4);border-top:var(--bw) solid var(--color-border);}
1235
+ .fdy-table-footer__info{font-size:var(--text-sm);color:var(--color-text-muted);}
1236
+
1237
+ /* Column filter — funnel button injected into a filterable <th> */
1238
+ .fdy-table__filterbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-left:var(--space-1);padding:0;vertical-align:middle;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-subtle);cursor:pointer;}
1239
+ .fdy-table__filterbtn:hover{background:var(--color-surface-3);color:var(--color-text);}
1240
+ .fdy-table__filterbtn:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1241
+ .fdy-table__filterbtn.is-active{color:var(--color-primary-strong);}
1242
+ .fdy-table__filterbtn svg{width:.85rem;height:.85rem;}
1243
+
1244
+ /* Filter popover (position:fixed, appended to <body> so overflow can't clip it) */
1245
+ .fdy-filter{position:fixed;z-index:130;min-width:14rem;max-width:18rem;padding:var(--space-3);background:var(--color-surface);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);text-transform:none;letter-spacing:normal;font-weight:var(--weight-regular);color:var(--color-text);}
1246
+ .fdy-filter__title{font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-wide);margin-bottom:var(--space-2);}
1247
+ .fdy-filter__list{display:flex;flex-direction:column;gap:var(--space-1);max-height:12rem;overflow:auto;}
1248
+ .fdy-filter__check{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;}
1249
+ .fdy-filter__range{display:flex;align-items:center;gap:var(--space-2);}
1250
+ .fdy-filter__range .fdy-input{width:6rem;}
1251
+ .fdy-filter__foot{display:flex;justify-content:space-between;gap:var(--space-2);margin-top:var(--space-3);}
1252
+
1253
+ /* Bulk-action bar — appears above the table body once rows are selected */
1254
+ .fdy-table-bulkbar{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-4);background:var(--color-primary-soft);border-bottom:var(--bw) solid var(--color-border);color:var(--color-primary-strong);font-size:var(--text-sm);}
1255
+ .fdy-table-bulkbar[hidden]{display:none;}
1256
+ .fdy-table-bulkbar__count{font-weight:var(--weight-semibold);white-space:nowrap;}
1257
+ .fdy-table-bulkbar__spacer{flex:1;}
1258
+ .fdy-table-bulkbar__actions{display:flex;gap:var(--space-2);}
1259
+
1260
+ /* Freeday — Tabs (WAI-ARIA APG) */
1261
+ .fdy-tabs__list{display:flex;gap:var(--space-1);border-bottom:var(--bw) solid var(--color-border);overflow-x:auto;}
1262
+ .fdy-tabs__tab{appearance:none;border:0;background:transparent;cursor:pointer;white-space:nowrap;font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);padding:var(--space-3) var(--space-4);border-bottom:2px solid transparent;margin-bottom:-1px;transition:color var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
1263
+ .fdy-tabs__tab:hover{color:var(--color-text);}
1264
+ .fdy-tabs__tab[aria-selected="true"]{color:var(--color-primary-strong);border-bottom-color:var(--color-primary);}
1265
+ .fdy-tabs__tab:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1266
+ .fdy-tabs__panel{padding:var(--space-5) 0;}
1267
+ .fdy-tabs__panel[hidden]{display:none;}
1268
+ /* Reveal the newly-shown panel on tab switch (fade + rise), reduced-motion gated. */
1269
+ @media (prefers-reduced-motion:no-preference){.fdy-tabs__panel:not([hidden]){animation:fdy-combo-in var(--dur-base) var(--ease-standard);}}
1270
+
1271
+ /* Freeday — Timeline (vertical event feed: dot markers on a connector line). Pure CSS. */
1272
+ .fdy-timeline{list-style:none;margin:0;padding:0;}
1273
+ .fdy-timeline__item{position:relative;padding:0 0 var(--space-5) var(--space-6);border-left:2px solid var(--color-border);}
1274
+ .fdy-timeline__item:last-child{border-left-color:transparent;padding-bottom:0;}
1275
+ .fdy-timeline__marker{position:absolute;left:0;top:.15rem;transform:translateX(-50%);width:.85rem;height:.85rem;border-radius:var(--radius-full);background:var(--color-primary);border:2px solid var(--color-surface);box-shadow:0 0 0 2px var(--color-border);}
1276
+ .fdy-timeline__item--success .fdy-timeline__marker{background:var(--color-success);}
1277
+ .fdy-timeline__item--warning .fdy-timeline__marker{background:var(--color-warning);}
1278
+ .fdy-timeline__item--danger .fdy-timeline__marker{background:var(--color-danger);}
1279
+ .fdy-timeline__item--muted .fdy-timeline__marker{background:var(--color-border-strong);}
1280
+ .fdy-timeline__time{font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums;}
1281
+ .fdy-timeline__title{margin:0;font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-text);}
1282
+ .fdy-timeline__text{margin:var(--space-1) 0 0;font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal);}
1283
+
1284
+ /* Freeday — Time picker (input-styled trigger + scrollable time-list popover).
1285
+ * Built by freeday-timepicker.js from an empty [data-fdy-timepicker] wrapper.
1286
+ * Trigger visual mirrors the date picker for a consistent control family. */
1287
+ .fdy-timepicker{position:relative;display:inline-block;width:100%;max-width:11rem;}
1288
+ .fdy-timepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1289
+ .fdy-timepicker__trigger:hover{border-color:var(--color-text-muted);}
1290
+ .fdy-timepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1291
+ .fdy-timepicker__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1292
+ .fdy-timepicker--error .fdy-timepicker__trigger,.fdy-timepicker__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
1293
+ .fdy-timepicker--error .fdy-timepicker__trigger:focus-visible,.fdy-timepicker--error .fdy-timepicker__trigger.is-open,.fdy-timepicker__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
1294
+ .fdy-timepicker__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;}
1295
+ .fdy-timepicker__value--placeholder{color:var(--color-text-subtle);}
1296
+ .fdy-timepicker__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
1297
+ .fdy-timepicker__icon svg{display:block;width:1.05rem;height:1.05rem;}
1298
+
1299
+ .fdy-timepicker__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:100%;max-height:15rem;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);}
1300
+ .fdy-timepicker__panel[hidden]{display:none;}
1301
+ .fdy-timepicker__panel:focus-visible{outline:none;}
1302
+ .fdy-timepicker__opt{display:flex;align-items:center;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);font-variant-numeric:tabular-nums;cursor:pointer;white-space:nowrap;}
1303
+ .fdy-timepicker__opt:hover,.fdy-timepicker__opt.is-active{background:var(--color-surface-3);}
1304
+ .fdy-timepicker__opt[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
1305
+ @media (prefers-reduced-motion:no-preference){.fdy-timepicker__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
1306
+
1307
+ /* Freeday — Toast (transient notification) */
1308
+ .fdy-toast-region{position:fixed;z-index:200;bottom:var(--space-5);right:var(--space-5);display:flex;flex-direction:column;gap:var(--space-3);width:min(24rem,calc(100vw - var(--space-8)));pointer-events:none;}
1309
+ .fdy-toast{pointer-events:auto;display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);background:var(--color-inverse-surface);color:var(--color-inverse-text);box-shadow:var(--shadow-3);}
1310
+ .fdy-toast__accent{flex:none;width:.25rem;align-self:stretch;border-radius:var(--radius-full);background:var(--color-primary);}
1311
+ .fdy-toast--success .fdy-toast__accent{background:var(--color-success);}
1312
+ .fdy-toast--warning .fdy-toast__accent{background:var(--color-warning);}
1313
+ .fdy-toast--danger .fdy-toast__accent{background:var(--color-danger);}
1314
+ .fdy-toast--info .fdy-toast__accent{background:var(--color-info);}
1315
+ .fdy-toast__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);font-size:var(--text-sm);}
1316
+ .fdy-toast__title{font-weight:var(--weight-semibold);}
1317
+ .fdy-toast__text{opacity:.88;line-height:var(--leading-normal);}
1318
+ .fdy-toast__close{flex:none;border:0;background:transparent;color:var(--color-inverse-text);opacity:.7;cursor:pointer;font-size:var(--text-lg);line-height:1;padding:0 var(--space-1);border-radius:var(--radius-sm);}
1319
+ .fdy-toast__close:hover{opacity:1;}
1320
+ .fdy-toast__close:focus-visible{outline:none;opacity:1;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-inverse-text) 40%,transparent);}
1321
+ .fdy-toast.is-leaving{opacity:0;transform:translateX(16px);transition:opacity var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-standard);}
1322
+ @media (prefers-reduced-motion:no-preference){.fdy-toast{animation:fdy-toast-in var(--dur-base) var(--ease-spring);}}
1323
+ @keyframes fdy-toast-in{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}
1324
+
1325
+ /* Freeday — Tooltip (CSS-only, hover/focus) */
1326
+ .fdy-tooltip-wrap{position:relative;display:inline-flex;}
1327
+ .fdy-tooltip{position:absolute;bottom:calc(100% + var(--space-2));left:50%;z-index:150;max-width:16rem;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:var(--leading-snug);color:var(--color-inverse-text);background:var(--color-inverse-surface);box-shadow:var(--shadow-2);opacity:0;visibility:hidden;pointer-events:none;transform:translateX(-50%) translateY(4px);transition:opacity var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard);}
1328
+ .fdy-tooltip::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);border:.3rem solid transparent;border-top-color:var(--color-inverse-surface);}
1329
+ .fdy-tooltip-wrap:hover .fdy-tooltip,.fdy-tooltip-wrap:focus-within .fdy-tooltip{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);}
1330
+ @media (prefers-reduced-motion:reduce){.fdy-tooltip{transition:none;transform:translateX(-50%);}}
1331
+
1332
+ /* Freeday — Tree view (hierarchy via nested native <details>: keyboard-toggle, zero-JS).
1333
+ * Branches expand/collapse; leaves are plain rows. Chevron + optional folder/file icons. */
1334
+ .fdy-tree{list-style:none;margin:0;padding:0;font-size:var(--text-sm);}
1335
+ .fdy-tree ul{list-style:none;margin:0;padding-left:var(--space-4);}
1336
+ .fdy-tree__branch > summary,.fdy-tree__leaf{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);color:var(--color-text);}
1337
+ .fdy-tree__branch > summary{list-style:none;cursor:pointer;}
1338
+ .fdy-tree__branch > summary::-webkit-details-marker{display:none;}
1339
+ .fdy-tree__branch > summary:hover,.fdy-tree__leaf:hover{background:var(--color-surface-2);}
1340
+ .fdy-tree__branch > summary:focus-visible{outline:none;box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
1341
+ .fdy-tree__chevron{flex:none;width:.9rem;height:.9rem;color:var(--color-text-subtle);transition:transform var(--dur-fast) var(--ease-standard);}
1342
+ .fdy-tree__branch[open] > summary .fdy-tree__chevron{transform:rotate(90deg);}
1343
+ .fdy-tree__icon{flex:none;width:1rem;height:1rem;color:var(--color-text-muted);}
1344
+ .fdy-tree__leaf{padding-left:calc(var(--space-2) * 2 + .9rem);}
1345
+ .fdy-tree__leaf .fdy-tree__icon{color:var(--color-text-subtle);}
1346
+
1347
+ /* Checkbox variant — a selectable tree (cascading parent/child via freeday-tree.js).
1348
+ * A native <input class="fdy-checkbox"> sits at the start of every row; a partially
1349
+ * selected branch shows the native :indeterminate dash. The checkbox stops click
1350
+ * propagation, so toggling selection never expands/collapses the branch. */
1351
+ .fdy-tree--checkbox .fdy-tree__check{flex:none;}
1352
+ .fdy-tree--checkbox .fdy-tree__leaf{padding-left:calc(var(--space-2) + .9rem + var(--space-2));}