@dodlhuat/basix 1.2.0 → 1.2.1

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 (93) hide show
  1. package/README.md +56 -1
  2. package/css/accordion.scss +86 -87
  3. package/css/alert.scss +137 -137
  4. package/css/button.scss +48 -0
  5. package/css/calendar.scss +957 -0
  6. package/css/card.scss +65 -65
  7. package/css/chart.scss +270 -157
  8. package/css/chat-bubbles.scss +134 -68
  9. package/css/chips.scss +109 -19
  10. package/css/colors.scss +32 -32
  11. package/css/datepicker.scss +336 -336
  12. package/css/defaults.scss +90 -90
  13. package/css/docs.scss +529 -0
  14. package/css/editor.scss +36 -0
  15. package/css/file-uploader.scss +1 -1
  16. package/css/flyout-menu.scss +361 -361
  17. package/css/form.scss +0 -15
  18. package/css/gallery.scss +65 -6
  19. package/css/grid.scss +41 -40
  20. package/css/group-picker.scss +345 -0
  21. package/css/guitar-chords.css +250 -250
  22. package/css/icons.scss +330 -330
  23. package/css/parameters.scss +3 -3
  24. package/css/placeholder.scss +33 -33
  25. package/css/popover.scss +206 -0
  26. package/css/progress.scss +76 -32
  27. package/css/properties.scss +51 -36
  28. package/css/push-menu.scss +302 -174
  29. package/css/reset.scss +39 -39
  30. package/css/scrollbar.scss +62 -5
  31. package/css/sidebar-nav.scss +92 -0
  32. package/css/spinner.scss +65 -65
  33. package/css/stepper.scss +48 -12
  34. package/css/style.css +3159 -254
  35. package/css/style.css.map +1 -1
  36. package/css/style.min.css +1 -1
  37. package/css/style.scss +51 -45
  38. package/css/table.scss +199 -199
  39. package/css/tabs.scss +154 -123
  40. package/css/timeline.scss +83 -38
  41. package/css/timepicker.scss +100 -5
  42. package/css/toast.scss +81 -81
  43. package/css/virtual-dropdown.scss +35 -29
  44. package/js/calendar.js +532 -0
  45. package/js/calendar.ts +706 -0
  46. package/js/chart.js +573 -257
  47. package/js/chart.ts +692 -0
  48. package/js/code-viewer.js +10 -10
  49. package/js/code-viewer.ts +188 -188
  50. package/js/datepicker.ts +627 -627
  51. package/js/docs-nav.js +204 -0
  52. package/js/dropdown.ts +179 -179
  53. package/js/editor.js +50 -6
  54. package/js/editor.ts +483 -444
  55. package/js/file-uploader.js +1 -0
  56. package/js/file-uploader.ts +1 -0
  57. package/js/flyout-menu.js +14 -14
  58. package/js/flyout-menu.ts +249 -249
  59. package/js/form-builder.js +106 -106
  60. package/js/gallery.js +14 -8
  61. package/js/gallery.ts +245 -236
  62. package/js/group-picker.js +342 -0
  63. package/js/group-picker.ts +447 -0
  64. package/js/guitar-chords.js +268 -268
  65. package/js/lazy-loader.js +121 -121
  66. package/js/modal.ts +166 -166
  67. package/js/popover.js +163 -0
  68. package/js/popover.ts +219 -0
  69. package/js/position.js +108 -0
  70. package/js/position.ts +111 -0
  71. package/js/push-menu.js +113 -0
  72. package/js/push-menu.ts +284 -145
  73. package/js/request.js +50 -50
  74. package/js/scroll.ts +47 -47
  75. package/js/scrollbar.js +13 -0
  76. package/js/scrollbar.ts +324 -307
  77. package/js/select.ts +216 -216
  78. package/js/sidebar-nav.js +41 -0
  79. package/js/sidebar-nav.ts +66 -0
  80. package/js/table.ts +452 -452
  81. package/js/tabs.ts +279 -279
  82. package/js/theme.js +17 -6
  83. package/js/theme.ts +234 -224
  84. package/js/toast.ts +137 -137
  85. package/js/tooltip.js +6 -60
  86. package/js/tooltip.ts +184 -251
  87. package/js/tsconfig.json +18 -18
  88. package/js/utils.ts +83 -83
  89. package/js/virtual-dropdown.js +25 -25
  90. package/js/virtual-dropdown.ts +365 -365
  91. package/package.json +39 -39
  92. package/js/index.js +0 -816
  93. package/js/index.ts +0 -987
@@ -0,0 +1,957 @@
1
+ // ============================================================
2
+ // calendar.scss — Basix Calendar Component Styles
3
+ //
4
+ // Integration principles:
5
+ // - No hard-coded colours — uses Basix CSS custom properties
6
+ // - No global reset
7
+ // - BEM: .cal / .cal__* / is-* / has-*
8
+ // - State classes match Basix convention: .is-today, .is-selected,
9
+ // .is-disabled, .has-events, .active, .error, .success
10
+ // - Font, spacing, radius, border — all from Basix tokens
11
+ // - Event pills accept any Basix badge/alert class as className
12
+ // ============================================================
13
+
14
+ @use "parameters" as *;
15
+
16
+ .cal {
17
+ --cal-spacing-xs: 4px;
18
+ --cal-spacing-sm: 8px;
19
+ --cal-spacing-md: 12px;
20
+ --cal-spacing-lg: 16px;
21
+
22
+ --cal-bg: var(--background);
23
+ --cal-bg-alt: var(--secondary-background);
24
+ --cal-bg-hover: var(--hover);
25
+
26
+ --cal-border: var(--divider);
27
+
28
+ --cal-text: var(--primary-text);
29
+ --cal-text-muted: var(--secondary-text);
30
+
31
+ --cal-accent: var(--accent-color);
32
+ --cal-accent-light: var(--accent-color-lighten);
33
+ --cal-accent-text: #fff;
34
+
35
+ --cal-today-ring: var(--accent-color);
36
+
37
+ --cal-hour-height: 48px;
38
+ --cal-time-col-width: 52px;
39
+
40
+ --cal-radius: #{$border-radius};
41
+ --cal-radius-sm: calc(#{$border-radius} * 0.5);
42
+
43
+ font-family: var(--font-family, 'Outfit', sans-serif);
44
+ color: var(--cal-text);
45
+ box-sizing: border-box;
46
+ width: 100%;
47
+ -webkit-tap-highlight-color: transparent;
48
+ }
49
+
50
+ .cal *,
51
+ .cal *::before,
52
+ .cal *::after {
53
+ box-sizing: inherit;
54
+ }
55
+
56
+ // ------------------------------------------------------------------
57
+ // Header
58
+ // ------------------------------------------------------------------
59
+
60
+ .cal__header {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: var(--cal-spacing-sm);
64
+ margin-bottom: var(--cal-spacing-lg);
65
+ flex-wrap: wrap;
66
+ }
67
+
68
+ .cal__title {
69
+ flex: 1;
70
+ min-width: 120px;
71
+ font-size: 1.25rem;
72
+ font-weight: 700;
73
+ color: var(--cal-text);
74
+ margin: 0;
75
+ letter-spacing: -0.02em;
76
+ }
77
+
78
+ .cal__nav {
79
+ display: flex;
80
+ gap: var(--cal-spacing-xs);
81
+ align-items: center;
82
+ }
83
+
84
+ .cal__btn {
85
+ display: inline-flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ gap: var(--cal-spacing-xs);
89
+ padding: 6px var(--cal-spacing-md);
90
+ font-family: inherit;
91
+ font-size: 0.8125rem;
92
+ font-weight: 500;
93
+ line-height: 1.5;
94
+ cursor: pointer;
95
+ border: 1px solid var(--cal-border);
96
+ border-radius: var(--cal-radius);
97
+ background: transparent;
98
+ color: var(--cal-text);
99
+ transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
100
+ white-space: nowrap;
101
+
102
+ &:hover {
103
+ background: var(--cal-bg-hover);
104
+ }
105
+
106
+ &:focus-visible {
107
+ outline: 2px solid var(--cal-accent);
108
+ outline-offset: 2px;
109
+ }
110
+
111
+ &:active {
112
+ transform: scale(0.95);
113
+ }
114
+
115
+ &--active,
116
+ &[aria-pressed="true"] {
117
+ background: var(--cal-accent);
118
+ border-color: var(--cal-accent);
119
+ color: var(--cal-accent-text);
120
+ font-weight: 600;
121
+ }
122
+
123
+ .icon-svg {
124
+ width: 16px;
125
+ height: 16px;
126
+ fill: currentColor;
127
+ vertical-align: middle;
128
+ }
129
+ }
130
+
131
+ .cal__view-toggle {
132
+ display: flex;
133
+ background: var(--cal-bg-alt);
134
+ border-radius: var(--cal-radius);
135
+ padding: 3px;
136
+ gap: 2px;
137
+ position: relative;
138
+
139
+ .cal__btn {
140
+ border: none;
141
+ border-radius: calc(var(--cal-radius) - 2px);
142
+ padding: 5px 14px;
143
+ font-size: 0.75rem;
144
+ background: transparent;
145
+ color: var(--cal-text-muted);
146
+ transition: color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
147
+ position: relative;
148
+ z-index: 1;
149
+
150
+ &--active,
151
+ &[aria-pressed="true"] {
152
+ background: var(--cal-bg);
153
+ color: var(--cal-text);
154
+ font-weight: 600;
155
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.03);
156
+ }
157
+ }
158
+ }
159
+
160
+ // ------------------------------------------------------------------
161
+ // Body wrapper
162
+ // ------------------------------------------------------------------
163
+
164
+ .cal__body {
165
+ width: 100%;
166
+ }
167
+
168
+ // ------------------------------------------------------------------
169
+ // Month View
170
+ // ------------------------------------------------------------------
171
+
172
+ .cal__month-grid {
173
+ display: grid;
174
+ grid-template-columns: repeat(7, minmax(0, 1fr));
175
+ border: 1px solid var(--cal-border);
176
+ border-radius: var(--cal-radius);
177
+ overflow: hidden;
178
+ gap: 1px;
179
+ background: var(--cal-border);
180
+ }
181
+
182
+ .cal__weekday {
183
+ background: var(--cal-bg-alt);
184
+ padding: var(--cal-spacing-sm) var(--cal-spacing-xs);
185
+ text-align: center;
186
+ font-size: 0.6875rem;
187
+ font-weight: 600;
188
+ color: var(--cal-text-muted);
189
+ letter-spacing: 0.06em;
190
+ text-transform: uppercase;
191
+ }
192
+
193
+ .cal__day {
194
+ background: var(--cal-bg);
195
+ padding: var(--cal-spacing-xs) var(--cal-spacing-sm);
196
+ min-height: 88px;
197
+ cursor: pointer;
198
+ transition: background 0.15s ease;
199
+ position: relative;
200
+
201
+ &:hover {
202
+ background: var(--cal-bg-hover);
203
+ }
204
+
205
+ &:focus-visible {
206
+ outline: 2px solid var(--cal-accent);
207
+ outline-offset: -2px;
208
+ z-index: 1;
209
+ }
210
+
211
+ &--empty {
212
+ background: var(--cal-bg-alt);
213
+ cursor: default;
214
+ pointer-events: none;
215
+ }
216
+
217
+ &--outside {
218
+ .cal__day-num {
219
+ opacity: 0.25;
220
+ }
221
+ .cal__day-events {
222
+ opacity: 0.25;
223
+ }
224
+ }
225
+
226
+ &.is-today .cal__day-num {
227
+ background: var(--cal-today-ring);
228
+ color: var(--cal-accent-text);
229
+ border-radius: 50%;
230
+ font-weight: 700;
231
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cal-accent) 20%, transparent);
232
+ }
233
+
234
+ &.is-selected {
235
+ background: color-mix(in srgb, var(--cal-accent) 6%, var(--cal-bg));
236
+
237
+ .cal__day-num {
238
+ background: var(--cal-accent);
239
+ color: var(--cal-accent-text);
240
+ border-radius: 50%;
241
+ font-weight: 700;
242
+ box-shadow: 0 2px 8px color-mix(in srgb, var(--cal-accent) 35%, transparent);
243
+ }
244
+ }
245
+
246
+ &.has-events::after {
247
+ content: '';
248
+ display: none;
249
+ position: absolute;
250
+ bottom: 6px;
251
+ left: 50%;
252
+ transform: translateX(-50%);
253
+ width: 5px;
254
+ height: 5px;
255
+ border-radius: 50%;
256
+ background: var(--cal-accent);
257
+ }
258
+ }
259
+
260
+ .cal__day-num {
261
+ display: inline-flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ width: 28px;
265
+ height: 28px;
266
+ font-size: 0.8125rem;
267
+ font-weight: 500;
268
+ color: var(--cal-text);
269
+ margin-bottom: var(--cal-spacing-xs);
270
+ flex-shrink: 0;
271
+ border-radius: 50%;
272
+ transition: background 0.2s ease, color 0.2s ease, box-shadow 0.25s ease, transform 0.15s ease;
273
+ }
274
+
275
+ .cal__day-events {
276
+ display: flex;
277
+ flex-direction: column;
278
+ gap: 2px;
279
+ overflow: hidden;
280
+ }
281
+
282
+ // Event pills — use badge color semantics for the left border accent
283
+ .cal__event-pill {
284
+ font-size: 0.6875rem;
285
+ line-height: 1.4;
286
+ padding: 2px 6px;
287
+ border-radius: var(--cal-radius-sm);
288
+ background: var(--cal-bg-alt);
289
+ color: var(--cal-text);
290
+ white-space: nowrap;
291
+ overflow: hidden;
292
+ text-overflow: ellipsis;
293
+ cursor: pointer;
294
+ border: none;
295
+ border-left: 2px solid var(--cal-accent-light);
296
+ display: block;
297
+ text-align: left;
298
+ width: 100%;
299
+ transition: background 0.12s ease, transform 0.1s ease;
300
+
301
+ &:hover {
302
+ background: var(--cal-bg-hover);
303
+ }
304
+
305
+ &:active {
306
+ transform: scale(0.97);
307
+ }
308
+
309
+ &:focus-visible {
310
+ outline: 2px solid var(--cal-accent);
311
+ outline-offset: 1px;
312
+ }
313
+
314
+ // Badge-class color mapping for left border
315
+ &.badge-success { border-left-color: var(--success); }
316
+ &.badge-warning { border-left-color: var(--warning); }
317
+ &.badge-error { border-left-color: var(--error); }
318
+ &.badge-info { border-left-color: var(--accent-color); }
319
+ }
320
+
321
+ .cal__event-more {
322
+ font-size: 0.625rem;
323
+ font-weight: 600;
324
+ color: var(--cal-accent);
325
+ padding: 1px 6px;
326
+ cursor: pointer;
327
+ }
328
+
329
+ .cal__event-time {
330
+ font-weight: 600;
331
+ margin-right: 3px;
332
+ opacity: 0.7;
333
+ }
334
+
335
+ // ------------------------------------------------------------------
336
+ // Week View
337
+ // ------------------------------------------------------------------
338
+
339
+ .cal__week {
340
+ border: 1px solid var(--cal-border);
341
+ border-radius: var(--cal-radius);
342
+ overflow: hidden;
343
+ }
344
+
345
+ .cal__week-head {
346
+ display: grid;
347
+ grid-template-columns: var(--cal-time-col-width) repeat(7, minmax(0, 1fr));
348
+ background: var(--cal-bg-alt);
349
+ border-bottom: 1px solid var(--cal-border);
350
+ overflow-y: auto;
351
+ scrollbar-gutter: stable;
352
+ scrollbar-width: thin;
353
+ scrollbar-color: transparent transparent;
354
+
355
+ &::-webkit-scrollbar {
356
+ width: 5px;
357
+ }
358
+
359
+ &::-webkit-scrollbar-track,
360
+ &::-webkit-scrollbar-thumb {
361
+ background: transparent;
362
+ }
363
+ }
364
+
365
+ .cal__week-head-time {
366
+ padding: var(--cal-spacing-sm) var(--cal-spacing-xs);
367
+ font-size: 0.6875rem;
368
+ color: var(--cal-text-muted);
369
+ }
370
+
371
+ .cal__week-head-day {
372
+ padding: var(--cal-spacing-sm) var(--cal-spacing-xs);
373
+ text-align: center;
374
+ font-size: 0.6875rem;
375
+ font-weight: 600;
376
+ color: var(--cal-text-muted);
377
+ border-left: 1px solid var(--cal-border);
378
+ cursor: pointer;
379
+ text-transform: uppercase;
380
+ letter-spacing: 0.04em;
381
+
382
+ span {
383
+ display: inline-flex;
384
+ align-items: center;
385
+ justify-content: center;
386
+ font-size: 1.0625rem;
387
+ font-weight: 600;
388
+ color: var(--cal-text);
389
+ line-height: 1;
390
+ width: 32px;
391
+ height: 32px;
392
+ border-radius: 50%;
393
+ margin-top: 2px;
394
+ transition: background 0.2s ease, color 0.2s ease, box-shadow 0.25s ease;
395
+ text-transform: none;
396
+ letter-spacing: normal;
397
+ }
398
+
399
+ &.is-today span {
400
+ background: var(--cal-today-ring);
401
+ color: var(--cal-accent-text);
402
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cal-accent) 20%, transparent);
403
+ }
404
+
405
+ &.is-selected span {
406
+ background: var(--cal-accent);
407
+ color: var(--cal-accent-text);
408
+ }
409
+ }
410
+
411
+ .cal__allday {
412
+ display: grid;
413
+ grid-template-columns: var(--cal-time-col-width) repeat(7, minmax(0, 1fr));
414
+ border-bottom: 1px solid var(--cal-border);
415
+ min-height: 32px;
416
+ background: var(--cal-bg);
417
+ overflow-y: auto;
418
+ scrollbar-gutter: stable;
419
+ scrollbar-width: thin;
420
+ scrollbar-color: transparent transparent;
421
+
422
+ &::-webkit-scrollbar {
423
+ width: 5px;
424
+ }
425
+
426
+ &::-webkit-scrollbar-track,
427
+ &::-webkit-scrollbar-thumb {
428
+ background: transparent;
429
+ }
430
+ }
431
+
432
+ .cal__allday-label {
433
+ padding: var(--cal-spacing-xs);
434
+ font-size: 0.625rem;
435
+ color: var(--cal-text-muted);
436
+ display: flex;
437
+ align-items: flex-start;
438
+ padding-top: 6px;
439
+ font-weight: 500;
440
+ }
441
+
442
+ .cal__allday-col {
443
+ border-left: 1px solid var(--cal-border);
444
+ padding: 3px;
445
+ display: flex;
446
+ flex-direction: column;
447
+ gap: 2px;
448
+ }
449
+
450
+ .cal__week-body {
451
+ overflow-y: auto;
452
+ max-height: 480px;
453
+ position: relative;
454
+ background: var(--cal-bg);
455
+ scrollbar-width: thin;
456
+ scrollbar-gutter: stable;
457
+ scrollbar-color: var(--cal-border) transparent;
458
+
459
+ &::-webkit-scrollbar {
460
+ width: 5px;
461
+ }
462
+
463
+ &::-webkit-scrollbar-track {
464
+ background: transparent;
465
+ }
466
+
467
+ &::-webkit-scrollbar-thumb {
468
+ background: var(--cal-border);
469
+ border-radius: 3px;
470
+ }
471
+ }
472
+
473
+ .cal__week-grid {
474
+ display: grid;
475
+ grid-template-columns: var(--cal-time-col-width) repeat(7, minmax(0, 1fr));
476
+ position: relative;
477
+ }
478
+
479
+ .cal__time-col {
480
+ display: flex;
481
+ flex-direction: column;
482
+ background: var(--cal-bg-alt);
483
+ }
484
+
485
+ .cal__time-slot {
486
+ height: var(--cal-hour-height);
487
+ display: flex;
488
+ align-items: flex-start;
489
+ padding-top: 3px;
490
+ padding-right: var(--cal-spacing-sm);
491
+ font-size: 0.625rem;
492
+ font-weight: 500;
493
+ color: var(--cal-text-muted);
494
+ justify-content: flex-end;
495
+ border-top: 1px solid var(--cal-border);
496
+ flex-shrink: 0;
497
+
498
+ &:first-child {
499
+ border-top: none;
500
+ }
501
+ }
502
+
503
+ .cal__day-col {
504
+ border-left: 1px solid var(--cal-border);
505
+ position: relative;
506
+ }
507
+
508
+ .cal__day-col-hour {
509
+ height: var(--cal-hour-height);
510
+ border-top: 1px solid var(--cal-border);
511
+ flex-shrink: 0;
512
+ position: relative;
513
+
514
+ &:first-child {
515
+ border-top: none;
516
+ }
517
+
518
+ &::after {
519
+ content: '';
520
+ display: block;
521
+ position: absolute;
522
+ left: 0;
523
+ right: 0;
524
+ top: 50%;
525
+ height: 1px;
526
+ background: var(--cal-border);
527
+ opacity: 0.4;
528
+ pointer-events: none;
529
+ }
530
+ }
531
+
532
+ .cal__week-event {
533
+ position: absolute;
534
+ left: 2px;
535
+ right: 2px;
536
+ border-radius: var(--cal-radius-sm);
537
+ font-size: 0.6875rem;
538
+ line-height: 1.3;
539
+ padding: 3px 6px;
540
+ overflow: hidden;
541
+ cursor: pointer;
542
+ background: color-mix(in srgb, var(--cal-accent) 10%, var(--cal-bg));
543
+ color: var(--cal-text);
544
+ border-left: 3px solid var(--cal-accent);
545
+ z-index: 1;
546
+ transition: box-shadow 0.15s ease, transform 0.1s ease;
547
+
548
+ &:hover {
549
+ z-index: 2;
550
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
551
+ transform: translateY(-1px);
552
+ }
553
+
554
+ &:active {
555
+ transform: scale(0.98);
556
+ }
557
+
558
+ &:focus-visible {
559
+ outline: 2px solid var(--cal-accent);
560
+ outline-offset: 1px;
561
+ z-index: 3;
562
+ }
563
+
564
+ // Badge-class color mapping
565
+ &.badge-success {
566
+ border-left-color: var(--success);
567
+ background: color-mix(in srgb, var(--success) 10%, var(--cal-bg));
568
+ }
569
+ &.badge-warning {
570
+ border-left-color: var(--warning);
571
+ background: color-mix(in srgb, var(--warning) 10%, var(--cal-bg));
572
+ }
573
+ &.badge-error {
574
+ border-left-color: var(--error);
575
+ background: color-mix(in srgb, var(--error) 10%, var(--cal-bg));
576
+ }
577
+ &.badge-info {
578
+ border-left-color: var(--accent-color);
579
+ background: color-mix(in srgb, var(--accent-color) 10%, var(--cal-bg));
580
+ }
581
+ }
582
+
583
+ // Now-line
584
+ .cal__now-line {
585
+ position: absolute;
586
+ left: 0;
587
+ right: 0;
588
+ height: 2px;
589
+ background: var(--error);
590
+ z-index: 5;
591
+ pointer-events: none;
592
+
593
+ &::before {
594
+ content: '';
595
+ display: block;
596
+ position: absolute;
597
+ left: -5px;
598
+ top: -4px;
599
+ width: 10px;
600
+ height: 10px;
601
+ border-radius: 50%;
602
+ background: var(--error);
603
+ animation: cal-now-pulse 2s ease-in-out infinite;
604
+ }
605
+ }
606
+
607
+ // ------------------------------------------------------------------
608
+ // Agenda View
609
+ // ------------------------------------------------------------------
610
+
611
+ .cal__agenda {
612
+ border: 1px solid var(--cal-border);
613
+ border-radius: var(--cal-radius);
614
+ overflow: hidden;
615
+ }
616
+
617
+ .cal__agenda-day {
618
+ display: flex;
619
+ gap: var(--cal-spacing-lg);
620
+ padding: var(--cal-spacing-md) var(--cal-spacing-lg);
621
+ border-bottom: 1px solid var(--cal-border);
622
+
623
+ &:last-child {
624
+ border-bottom: none;
625
+ }
626
+
627
+ &.is-today {
628
+ background: color-mix(in srgb, var(--cal-accent) 4%, var(--cal-bg));
629
+ }
630
+ }
631
+
632
+ .cal__agenda-date {
633
+ display: flex;
634
+ flex-direction: column;
635
+ align-items: center;
636
+ min-width: 44px;
637
+ flex-shrink: 0;
638
+ }
639
+
640
+ .cal__agenda-dow {
641
+ font-size: 0.625rem;
642
+ color: var(--cal-text-muted);
643
+ text-transform: uppercase;
644
+ letter-spacing: 0.06em;
645
+ font-weight: 600;
646
+ }
647
+
648
+ .cal__agenda-num {
649
+ display: inline-flex;
650
+ align-items: center;
651
+ justify-content: center;
652
+ width: 34px;
653
+ height: 34px;
654
+ font-size: 1rem;
655
+ font-weight: 700;
656
+ color: var(--cal-text);
657
+ border-radius: 50%;
658
+ margin-top: 2px;
659
+ transition: background 0.2s ease, color 0.2s ease;
660
+
661
+ &.is-today {
662
+ background: var(--cal-today-ring);
663
+ color: var(--cal-accent-text);
664
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cal-accent) 20%, transparent);
665
+ }
666
+ }
667
+
668
+ .cal__agenda-events {
669
+ flex: 1;
670
+ display: flex;
671
+ flex-direction: column;
672
+ gap: var(--cal-spacing-sm);
673
+ padding-top: 4px;
674
+ min-width: 0;
675
+ }
676
+
677
+ .cal__agenda-event {
678
+ display: flex;
679
+ align-items: baseline;
680
+ gap: var(--cal-spacing-sm);
681
+ padding: var(--cal-spacing-sm) var(--cal-spacing-md);
682
+ border-radius: var(--cal-radius-sm);
683
+ background: var(--cal-bg-alt);
684
+ border-left: 3px solid var(--cal-accent-light);
685
+ cursor: pointer;
686
+ transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
687
+
688
+ &:hover {
689
+ background: var(--cal-bg-hover);
690
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
691
+ }
692
+
693
+ &:active {
694
+ transform: scale(0.98);
695
+ }
696
+
697
+ &:focus-visible {
698
+ outline: 2px solid var(--cal-accent);
699
+ outline-offset: 1px;
700
+ }
701
+
702
+ // Badge-class color mapping
703
+ &.badge-success { border-left-color: var(--success); }
704
+ &.badge-warning { border-left-color: var(--warning); }
705
+ &.badge-error { border-left-color: var(--error); }
706
+ &.badge-info { border-left-color: var(--accent-color); }
707
+ }
708
+
709
+ .cal__agenda-event-time {
710
+ font-size: 0.75rem;
711
+ color: var(--cal-text-muted);
712
+ font-weight: 600;
713
+ white-space: nowrap;
714
+ min-width: 110px;
715
+ flex-shrink: 0;
716
+ }
717
+
718
+ .cal__agenda-event-title {
719
+ font-size: 0.875rem;
720
+ color: var(--cal-text);
721
+ font-weight: 500;
722
+ white-space: nowrap;
723
+ overflow: hidden;
724
+ text-overflow: ellipsis;
725
+ }
726
+
727
+ .cal__agenda-empty {
728
+ padding: var(--cal-spacing-lg);
729
+ color: var(--cal-text-muted);
730
+ font-size: 0.875rem;
731
+ text-align: center;
732
+ }
733
+
734
+ // ------------------------------------------------------------------
735
+ // Responsive — mobile-first refinements
736
+ // ------------------------------------------------------------------
737
+
738
+ @media (max-width: 600px) {
739
+ .cal__header {
740
+ gap: var(--cal-spacing-xs);
741
+ }
742
+
743
+ .cal__title {
744
+ font-size: 1.0625rem;
745
+ order: -1;
746
+ width: 100%;
747
+ }
748
+
749
+ .cal__nav {
750
+ flex: 1;
751
+ }
752
+
753
+ .cal__view-toggle {
754
+ padding: 2px;
755
+ gap: 1px;
756
+
757
+ .cal__btn {
758
+ padding: 4px 10px;
759
+ font-size: 0.6875rem;
760
+ }
761
+ }
762
+
763
+ // Month grid — borderless, airy, centered numbers
764
+ .cal__month-grid {
765
+ border: none;
766
+ border-radius: 0;
767
+ gap: 0;
768
+ background: transparent;
769
+ }
770
+
771
+ .cal__weekday {
772
+ background: transparent;
773
+ padding: var(--cal-spacing-sm) 0;
774
+ font-size: 0.625rem;
775
+ }
776
+
777
+ .cal__day {
778
+ min-height: 52px;
779
+ padding: var(--cal-spacing-xs) 0;
780
+ display: flex;
781
+ flex-direction: column;
782
+ align-items: center;
783
+ justify-content: flex-start;
784
+ background: transparent;
785
+
786
+ &:hover {
787
+ background: transparent;
788
+
789
+ .cal__day-num {
790
+ background: var(--cal-bg-hover);
791
+ }
792
+ }
793
+
794
+ &--empty {
795
+ background: transparent;
796
+ }
797
+
798
+ &--outside {
799
+ .cal__day-num {
800
+ opacity: 0.25;
801
+ }
802
+ }
803
+
804
+ &.is-selected {
805
+ background: transparent;
806
+ }
807
+
808
+ &.has-events::after {
809
+ display: block;
810
+ position: static;
811
+ transform: none;
812
+ margin-top: 3px;
813
+ }
814
+ }
815
+
816
+ .cal__day-num {
817
+ width: 36px;
818
+ height: 36px;
819
+ font-size: 0.8125rem;
820
+ margin-bottom: 0;
821
+ }
822
+
823
+ .cal__day-events,
824
+ .cal__event-pill,
825
+ .cal__event-more {
826
+ display: none;
827
+ }
828
+
829
+ // Week view — compact
830
+ .cal {
831
+ --cal-time-col-width: 40px;
832
+ }
833
+
834
+ .cal__week-body {
835
+ max-height: 360px;
836
+ }
837
+
838
+ .cal__week-head-day {
839
+ font-size: 0.5625rem;
840
+ padding: var(--cal-spacing-xs) 2px;
841
+
842
+ span {
843
+ font-size: 0.875rem;
844
+ width: 28px;
845
+ height: 28px;
846
+ }
847
+ }
848
+
849
+ .cal__time-slot {
850
+ font-size: 0.5rem;
851
+ padding-right: 3px;
852
+ }
853
+
854
+ // Agenda — tighter
855
+ .cal__agenda-day {
856
+ padding: var(--cal-spacing-sm) var(--cal-spacing-md);
857
+ gap: var(--cal-spacing-md);
858
+ }
859
+
860
+ .cal__agenda-event {
861
+ padding: var(--cal-spacing-xs) var(--cal-spacing-sm);
862
+ flex-direction: column;
863
+ gap: 2px;
864
+ }
865
+
866
+ .cal__agenda-event-time {
867
+ min-width: 0;
868
+ font-size: 0.6875rem;
869
+ }
870
+
871
+ .cal__agenda-event-title {
872
+ font-size: 0.8125rem;
873
+ }
874
+ }
875
+
876
+ // ------------------------------------------------------------------
877
+ // Print styles
878
+ // ------------------------------------------------------------------
879
+
880
+ @media print {
881
+ .cal__header .cal__view-toggle,
882
+ .cal__header .cal__nav .cal__btn--today {
883
+ display: none;
884
+ }
885
+
886
+ .cal__week-body {
887
+ max-height: none;
888
+ overflow: visible;
889
+ }
890
+
891
+ .cal__month-grid,
892
+ .cal__week,
893
+ .cal__agenda {
894
+ border: 1px solid #ccc;
895
+ }
896
+ }
897
+
898
+ // ------------------------------------------------------------------
899
+ // Animation — staggered grid entrance + now-line pulse
900
+ // ------------------------------------------------------------------
901
+
902
+ @media (prefers-reduced-motion: no-preference) {
903
+ .cal__body {
904
+ animation: cal-slide-in 0.25s cubic-bezier(0.2, 0, 0, 1);
905
+ }
906
+
907
+ .cal__day,
908
+ .cal__agenda-day {
909
+ animation: cal-cell-in 0.3s cubic-bezier(0.2, 0, 0, 1) both;
910
+ }
911
+
912
+ // Stagger the first 5 rows (35 day cells) for a wave effect
913
+ @for $i from 1 through 49 {
914
+ .cal__month-grid .cal__day:nth-child(#{$i}) {
915
+ animation-delay: #{0.01s * $i};
916
+ }
917
+ }
918
+
919
+ @for $i from 1 through 10 {
920
+ .cal__agenda-day:nth-child(#{$i}) {
921
+ animation-delay: #{0.03s * $i};
922
+ }
923
+ }
924
+ }
925
+
926
+ @keyframes cal-slide-in {
927
+ from {
928
+ opacity: 0;
929
+ transform: translateY(8px);
930
+ }
931
+ to {
932
+ opacity: 1;
933
+ transform: translateY(0);
934
+ }
935
+ }
936
+
937
+ @keyframes cal-cell-in {
938
+ from {
939
+ opacity: 0;
940
+ transform: scale(0.96);
941
+ }
942
+ to {
943
+ opacity: 1;
944
+ transform: scale(1);
945
+ }
946
+ }
947
+
948
+ @keyframes cal-now-pulse {
949
+ 0%, 100% {
950
+ opacity: 1;
951
+ transform: scale(1);
952
+ }
953
+ 50% {
954
+ opacity: 0.5;
955
+ transform: scale(1.3);
956
+ }
957
+ }