@lekoala/slot-picker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +370 -0
  3. package/custom-elements.json +53 -0
  4. package/dist/slot-picker.css +597 -0
  5. package/dist/slot-picker.js +1382 -0
  6. package/dist/slot-picker.min.css +1 -0
  7. package/dist/slot-picker.min.js +36 -0
  8. package/dist/types/date.d.ts +23 -0
  9. package/dist/types/date.d.ts.map +1 -0
  10. package/dist/types/define.d.ts +2 -0
  11. package/dist/types/define.d.ts.map +1 -0
  12. package/dist/types/index.d.ts +6 -0
  13. package/dist/types/index.d.ts.map +1 -0
  14. package/dist/types/locales/ar.d.ts +20 -0
  15. package/dist/types/locales/ar.d.ts.map +1 -0
  16. package/dist/types/locales/de.d.ts +20 -0
  17. package/dist/types/locales/de.d.ts.map +1 -0
  18. package/dist/types/locales/en.d.ts +20 -0
  19. package/dist/types/locales/en.d.ts.map +1 -0
  20. package/dist/types/locales/es.d.ts +20 -0
  21. package/dist/types/locales/es.d.ts.map +1 -0
  22. package/dist/types/locales/fr.d.ts +20 -0
  23. package/dist/types/locales/fr.d.ts.map +1 -0
  24. package/dist/types/locales/hi.d.ts +20 -0
  25. package/dist/types/locales/hi.d.ts.map +1 -0
  26. package/dist/types/locales/id.d.ts +20 -0
  27. package/dist/types/locales/id.d.ts.map +1 -0
  28. package/dist/types/locales/it.d.ts +20 -0
  29. package/dist/types/locales/it.d.ts.map +1 -0
  30. package/dist/types/locales/ja.d.ts +20 -0
  31. package/dist/types/locales/ja.d.ts.map +1 -0
  32. package/dist/types/locales/ko.d.ts +20 -0
  33. package/dist/types/locales/ko.d.ts.map +1 -0
  34. package/dist/types/locales/nl.d.ts +20 -0
  35. package/dist/types/locales/nl.d.ts.map +1 -0
  36. package/dist/types/locales/pl.d.ts +20 -0
  37. package/dist/types/locales/pl.d.ts.map +1 -0
  38. package/dist/types/locales/pt-BR.d.ts +20 -0
  39. package/dist/types/locales/pt-BR.d.ts.map +1 -0
  40. package/dist/types/locales/pt-PT.d.ts +20 -0
  41. package/dist/types/locales/pt-PT.d.ts.map +1 -0
  42. package/dist/types/locales/ru.d.ts +20 -0
  43. package/dist/types/locales/ru.d.ts.map +1 -0
  44. package/dist/types/locales/tr.d.ts +20 -0
  45. package/dist/types/locales/tr.d.ts.map +1 -0
  46. package/dist/types/locales/zh-CN.d.ts +20 -0
  47. package/dist/types/locales/zh-CN.d.ts.map +1 -0
  48. package/dist/types/messages.d.ts +67 -0
  49. package/dist/types/messages.d.ts.map +1 -0
  50. package/dist/types/model.d.ts +213 -0
  51. package/dist/types/model.d.ts.map +1 -0
  52. package/dist/types/slot-picker.d.ts +182 -0
  53. package/dist/types/slot-picker.d.ts.map +1 -0
  54. package/dist/types/source.d.ts +45 -0
  55. package/dist/types/source.d.ts.map +1 -0
  56. package/dist/types/views/columns.d.ts +28 -0
  57. package/dist/types/views/columns.d.ts.map +1 -0
  58. package/dist/types/views/day.d.ts +27 -0
  59. package/dist/types/views/day.d.ts.map +1 -0
  60. package/dist/types/views/shared.d.ts +99 -0
  61. package/dist/types/views/shared.d.ts.map +1 -0
  62. package/docs/USE_CASES.md +197 -0
  63. package/package.json +148 -0
  64. package/src/date.js +66 -0
  65. package/src/define.js +5 -0
  66. package/src/index.js +25 -0
  67. package/src/locales/ar.js +18 -0
  68. package/src/locales/de.js +18 -0
  69. package/src/locales/en.js +18 -0
  70. package/src/locales/es.js +18 -0
  71. package/src/locales/fr.js +18 -0
  72. package/src/locales/hi.js +18 -0
  73. package/src/locales/id.js +18 -0
  74. package/src/locales/it.js +18 -0
  75. package/src/locales/ja.js +18 -0
  76. package/src/locales/ko.js +18 -0
  77. package/src/locales/nl.js +18 -0
  78. package/src/locales/pl.js +18 -0
  79. package/src/locales/pt-BR.js +18 -0
  80. package/src/locales/pt-PT.js +18 -0
  81. package/src/locales/ru.js +18 -0
  82. package/src/locales/tr.js +18 -0
  83. package/src/locales/zh-CN.js +18 -0
  84. package/src/messages.js +44 -0
  85. package/src/model.js +357 -0
  86. package/src/slot-picker.css +597 -0
  87. package/src/slot-picker.js +1094 -0
  88. package/src/source.js +87 -0
  89. package/src/views/columns.js +108 -0
  90. package/src/views/day.js +122 -0
  91. package/src/views/shared.js +157 -0
@@ -0,0 +1,597 @@
1
+ :where(slot-picker) {
2
+ --sp-bg: #ffffff;
3
+ --sp-fg: #1f2328;
4
+ --sp-muted: color-mix(in srgb, var(--sp-fg) 58%, var(--sp-bg));
5
+ --sp-border: color-mix(in srgb, var(--sp-fg) 16%, var(--sp-bg));
6
+ --sp-hover: color-mix(in srgb, var(--sp-fg) 5%, var(--sp-bg));
7
+ --sp-notice-hover-bg: color-mix(in srgb, var(--sp-fg) 12%, var(--sp-bg));
8
+ --sp-accent: #2563eb;
9
+ --sp-accent-fg: #ffffff;
10
+ --sp-accent-soft: color-mix(in srgb, var(--sp-accent) 16%, var(--sp-bg));
11
+ --sp-focus: var(--sp-accent);
12
+ --sp-radius: 0.5rem;
13
+ --sp-gap: 0.5rem;
14
+ --sp-day-gap: 0.75rem;
15
+ --sp-slot-columns: 3;
16
+ --sp-card-bg: transparent;
17
+ --sp-slot-block-size: 2.75rem;
18
+ /* Slot colors are their own theming surface so a `data-tone` can recolor a
19
+ single slot without touching focus or the rest of the picker. */
20
+ --sp-slot-bg: var(--sp-accent-soft);
21
+ --sp-slot-fg: var(--sp-fg);
22
+ --sp-slot-border: transparent;
23
+ --sp-slot-hover-bg: color-mix(in srgb, var(--sp-accent) 22%, var(--sp-bg));
24
+ --sp-slot-selected-bg: var(--sp-accent);
25
+ --sp-slot-selected-fg: var(--sp-accent-fg);
26
+ --sp-nav-size: 2.5rem;
27
+ /* Stable collapsed footprint. `--sp-day-header-block-size` is a minimum, not
28
+ a fixed height: the reserved area follows `max-visible-rows` so navigating
29
+ between sparse and empty ranges never shifts the page. */
30
+ --sp-day-header-block-size: 3.4rem;
31
+ --sp-collapsed-rows: var(--_sp-max-visible-rows, 5);
32
+ --sp-collapsed-body-block-size: calc(
33
+ var(--sp-collapsed-rows) *
34
+ (var(--sp-slot-block-size) + var(--sp-gap)) -
35
+ var(--sp-gap)
36
+ );
37
+ --sp-footer-block-size: 2.5rem;
38
+ /* Reserved height for the `home` shortcut when `home-date` is configured. */
39
+ --sp-shortcuts-block-size: 2.5rem;
40
+ --sp-collapsed-block-size: calc(
41
+ var(--sp-day-header-block-size) +
42
+ var(--sp-collapsed-body-block-size) +
43
+ var(--sp-footer-block-size)
44
+ );
45
+ /* Collapsed "show more" floats in the reserved footer band; the gradient
46
+ rises above that band to hint at availability that is not rendered. */
47
+ --sp-more-fade-size: 4rem;
48
+ --sp-more-bg: var(--sp-bg);
49
+ --sp-panel-min-block-size: calc(2 * var(--sp-slot-block-size) + var(--sp-gap));
50
+ /* `closed` is a normal day state; themes may restyle it entirely. */
51
+ --sp-closed-opacity: 0.55;
52
+ --sp-loading-fade-opacity: 0.72;
53
+ --sp-loading-fade-delay: 400ms;
54
+ display: block;
55
+ color: var(--sp-fg);
56
+ font: inherit;
57
+ }
58
+
59
+ .sp-visually-hidden {
60
+ position: absolute !important;
61
+ inline-size: 1px !important;
62
+ block-size: 1px !important;
63
+ padding: 0 !important;
64
+ margin: -1px !important;
65
+ overflow: hidden !important;
66
+ clip: rect(0 0 0 0) !important;
67
+ white-space: nowrap !important;
68
+ border: 0 !important;
69
+ }
70
+
71
+ .sp-shell {
72
+ display: block;
73
+ }
74
+
75
+ /* `previous`/`next` are a symmetric pair around a centered projection. They
76
+ are the only range-navigation chrome; `home` is not their mirror and lives
77
+ in `.sp-shortcuts` instead. */
78
+ .sp-projection {
79
+ display: grid;
80
+ grid-template-columns: auto minmax(0, 1fr) auto;
81
+ align-items: start;
82
+ gap: var(--sp-gap);
83
+ }
84
+
85
+ .sp-content {
86
+ position: relative;
87
+ min-inline-size: 0;
88
+ opacity: 1;
89
+ transition-property: opacity;
90
+ transition-duration: 160ms;
91
+ transition-timing-function: ease;
92
+ transition-delay: 0ms;
93
+ }
94
+
95
+ /* Slow loads fade the current projection to signal stale data, but only after
96
+ a delay: fast requests never flicker. `aria-busy` is the only state source. */
97
+ slot-picker[aria-busy="true"] .sp-content {
98
+ opacity: var(--sp-loading-fade-opacity, 0.72);
99
+ transition-delay: var(--sp-loading-fade-delay, 400ms);
100
+ }
101
+
102
+ /* Keep the delay (the stale hint), drop the animation. */
103
+ @media (prefers-reduced-motion: reduce) {
104
+ .sp-content {
105
+ transition-duration: 0ms;
106
+ }
107
+ }
108
+
109
+ /* Collapsed columns keep the same footprint whether the range is full, sparse,
110
+ or empty. Expanded content simply grows past this floor. */
111
+ slot-picker:not([layout="day"]) .sp-content {
112
+ min-block-size: var(--sp-collapsed-block-size);
113
+ }
114
+
115
+ /* Auxiliary, start-aligned shortcut. Rendered only when `homeDate` is outside
116
+ the visible range, i.e. when it would actually change something. */
117
+ .sp-shortcuts {
118
+ display: flex;
119
+ justify-content: flex-start;
120
+ margin-block-start: var(--sp-gap);
121
+ }
122
+
123
+ /* Keep the wrapper present (empty when `homeDate` is visible) so the shortcut
124
+ appearing never shifts the content below. */
125
+ slot-picker[home-date] .sp-shortcuts {
126
+ min-block-size: var(--sp-shortcuts-block-size, 2.5rem);
127
+ }
128
+
129
+ .sp-home {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ gap: 0.35rem;
133
+ padding: 0.25rem 0;
134
+ border: 0;
135
+ background: transparent;
136
+ color: var(--sp-accent);
137
+ font: inherit;
138
+ cursor: pointer;
139
+ }
140
+
141
+ .sp-home:hover {
142
+ text-decoration: underline;
143
+ }
144
+
145
+ .sp-grid {
146
+ display: grid;
147
+ grid-template-columns: repeat(var(--_sp-day-count, 5), minmax(0, 1fr));
148
+ gap: var(--sp-day-gap);
149
+ }
150
+
151
+ .sp-day {
152
+ min-inline-size: 0;
153
+ }
154
+
155
+ .sp-day-header {
156
+ position: relative;
157
+ display: grid;
158
+ justify-items: center;
159
+ gap: 0.1rem;
160
+ /* Deterministic leading: an inherited `normal` line-height can exceed the
161
+ reserved header height and break the stable footprint. */
162
+ line-height: 1.25;
163
+ box-sizing: border-box;
164
+ min-block-size: var(--sp-day-header-block-size);
165
+ padding-block: 0.15rem 0.55rem;
166
+ text-align: center;
167
+ }
168
+
169
+ .sp-weekday {
170
+ color: var(--sp-muted);
171
+ font-size: 0.85rem;
172
+ }
173
+
174
+ .sp-date {
175
+ font-size: 0.9rem;
176
+ font-weight: 650;
177
+ }
178
+
179
+ /* Notice indicator. Without `data-day-index` it is decorative; with it, it is
180
+ the accessible control used by notice-display="action". */
181
+ .sp-notice {
182
+ position: absolute;
183
+ inset-block-start: 0;
184
+ inset-inline-end: 0;
185
+ display: grid;
186
+ place-items: center;
187
+ inline-size: 1.5rem;
188
+ block-size: 1.5rem;
189
+ color: var(--sp-muted);
190
+ pointer-events: none;
191
+ }
192
+
193
+ .sp-notice[data-day-index] {
194
+ pointer-events: auto;
195
+ padding: 0;
196
+ border: 0;
197
+ border-radius: 50%;
198
+ background: transparent;
199
+ cursor: pointer;
200
+ transition: background-color 120ms ease;
201
+ }
202
+
203
+ .sp-notice[data-day-index]:hover {
204
+ background: var(--sp-notice-hover-bg);
205
+ color: var(--sp-fg);
206
+ }
207
+
208
+ .sp-notice-dot {
209
+ inline-size: 0.45rem;
210
+ block-size: 0.45rem;
211
+ border-radius: 50%;
212
+ background: currentColor;
213
+ }
214
+
215
+ .sp-slots {
216
+ display: grid;
217
+ gap: var(--sp-gap);
218
+ }
219
+
220
+ .sp-slot,
221
+ .sp-empty {
222
+ display: grid;
223
+ place-items: center;
224
+ min-block-size: var(--sp-slot-block-size);
225
+ box-sizing: border-box;
226
+ border-radius: var(--sp-radius);
227
+ font: inherit;
228
+ }
229
+
230
+ .sp-slot {
231
+ border: 1px solid var(--sp-slot-border);
232
+ background: var(--sp-slot-bg);
233
+ color: var(--sp-slot-fg);
234
+ cursor: pointer;
235
+ }
236
+
237
+ .sp-slot:hover:not(:disabled):not([aria-selected="true"]) {
238
+ background: var(--sp-slot-hover-bg);
239
+ }
240
+
241
+ .sp-slot[aria-selected="true"] {
242
+ background: var(--sp-slot-selected-bg);
243
+ color: var(--sp-slot-selected-fg);
244
+ }
245
+
246
+ .sp-slot:disabled {
247
+ cursor: not-allowed;
248
+ opacity: 0.45;
249
+ }
250
+
251
+ .sp-slot:focus-visible {
252
+ outline: 2px solid var(--sp-focus);
253
+ outline-offset: 2px;
254
+ }
255
+
256
+ .sp-slot[aria-selected="true"]:focus-visible {
257
+ outline-color: var(--sp-fg);
258
+ }
259
+
260
+ .sp-empty {
261
+ color: var(--sp-muted);
262
+ user-select: none;
263
+ }
264
+
265
+ .sp-nav {
266
+ display: grid;
267
+ place-items: center;
268
+ inline-size: var(--sp-nav-size);
269
+ block-size: var(--sp-nav-size);
270
+ margin-block-start: 0.45rem;
271
+ padding: 0;
272
+ border: 1px solid var(--sp-border);
273
+ border-radius: 50%;
274
+ background: var(--sp-bg);
275
+ color: var(--sp-fg);
276
+ cursor: pointer;
277
+ }
278
+
279
+ .sp-nav:hover:not(:disabled) {
280
+ background: var(--sp-hover);
281
+ }
282
+
283
+ .sp-nav:disabled {
284
+ cursor: not-allowed;
285
+ opacity: 0.4;
286
+ }
287
+
288
+ .sp-nav svg {
289
+ display: block;
290
+ inline-size: 1rem;
291
+ block-size: 1rem;
292
+ pointer-events: none;
293
+ }
294
+
295
+ [dir="rtl"] .sp-nav svg,
296
+ html[dir="rtl"] .sp-nav svg {
297
+ transform: scaleX(-1);
298
+ }
299
+
300
+ .sp-more {
301
+ display: flex;
302
+ justify-content: center;
303
+ margin-block-start: 1rem;
304
+ }
305
+
306
+ /* Collapsed: float the control inside the reserved footer band while the
307
+ gradient rises above it to suggest the availability that is not rendered.
308
+ The last rendered row stays fully interactive. */
309
+ slot-picker:not([expanded]) .sp-more {
310
+ position: absolute;
311
+ inset-inline: 0;
312
+ inset-block-end: 0;
313
+ display: grid;
314
+ place-items: end center;
315
+ margin-block-start: 0;
316
+ min-block-size: var(--sp-footer-block-size);
317
+ }
318
+
319
+ slot-picker:not([expanded]) .sp-more::before {
320
+ content: "";
321
+ position: absolute;
322
+ inset-inline: 0;
323
+ inset-block-end: 0;
324
+ block-size: var(--sp-more-fade-size, 4rem);
325
+ background: linear-gradient(to bottom, transparent, var(--sp-more-bg, var(--sp-bg)));
326
+ pointer-events: none;
327
+ }
328
+
329
+ /* Expanded: back to normal flow, overlay and gradient removed. */
330
+ slot-picker[expanded] .sp-more {
331
+ position: static;
332
+ }
333
+
334
+ slot-picker[expanded] .sp-more::before {
335
+ content: none;
336
+ }
337
+
338
+ .sp-more-button {
339
+ position: relative;
340
+ z-index: 1;
341
+ border: 0;
342
+ background: transparent;
343
+ color: var(--sp-accent);
344
+ font: inherit;
345
+ cursor: pointer;
346
+ }
347
+
348
+ .sp-status {
349
+ margin-block-end: 0.75rem;
350
+ color: var(--sp-muted);
351
+ text-align: center;
352
+ }
353
+
354
+ .sp-status-error {
355
+ color: var(--sp-fg);
356
+ }
357
+
358
+ .sp-day-empty {
359
+ display: grid;
360
+ place-items: center;
361
+ min-block-size: var(--sp-slot-block-size);
362
+ padding-inline: 0.5rem;
363
+ color: var(--sp-muted);
364
+ font-size: 0.9rem;
365
+ text-align: center;
366
+ }
367
+
368
+ /* A day closed by the application's opening rule. It stays in the civil
369
+ projection; only its presentation changes. */
370
+ .sp-day[data-closed],
371
+ .sp-panel[data-closed],
372
+ .sp-strip-day[data-closed] {
373
+ opacity: var(--sp-closed-opacity, 0.55);
374
+ }
375
+
376
+ .sp-range-empty {
377
+ display: grid;
378
+ justify-items: center;
379
+ align-content: center;
380
+ gap: 0.5rem;
381
+ box-sizing: border-box;
382
+ min-block-size: var(--sp-collapsed-block-size);
383
+ padding: 1.5rem 1rem;
384
+ border-radius: var(--sp-radius);
385
+ background: var(--sp-card-bg);
386
+ text-align: center;
387
+ }
388
+
389
+ slot-picker[layout="day"] .sp-range-empty {
390
+ min-block-size: var(--sp-panel-min-block-size);
391
+ }
392
+
393
+ /* Day layout: only the empty state needs a baseline, a populated panel keeps
394
+ its natural height. */
395
+ slot-picker[layout="day"] .sp-day-empty {
396
+ align-content: center;
397
+ min-block-size: var(--sp-panel-min-block-size);
398
+ }
399
+
400
+ .sp-range-empty-title {
401
+ font-size: 1rem;
402
+ }
403
+
404
+ .sp-range-empty-description {
405
+ margin: 0;
406
+ color: var(--sp-muted);
407
+ }
408
+
409
+ .sp-range-empty-actions {
410
+ display: flex;
411
+ flex-wrap: wrap;
412
+ gap: 0.5rem;
413
+ justify-content: center;
414
+ }
415
+
416
+ .sp-range-empty-next {
417
+ border: 0;
418
+ border-radius: var(--sp-radius);
419
+ padding: 0.6rem 1rem;
420
+ background: var(--sp-accent);
421
+ color: var(--sp-accent-fg);
422
+ font: inherit;
423
+ cursor: pointer;
424
+ }
425
+
426
+ .sp-range-empty-next:hover {
427
+ background: color-mix(in srgb, var(--sp-accent) 85%, var(--sp-bg));
428
+ }
429
+
430
+ .sp-range-empty-availability {
431
+ border: 1px solid var(--sp-border);
432
+ border-radius: var(--sp-radius);
433
+ padding: 0.6rem 1rem;
434
+ background: var(--sp-bg);
435
+ color: var(--sp-accent);
436
+ font: inherit;
437
+ cursor: pointer;
438
+ }
439
+
440
+ .sp-range-empty-availability:hover {
441
+ background: var(--sp-hover);
442
+ }
443
+
444
+ .sp-range-empty-next:focus-visible,
445
+ .sp-range-empty-availability:focus-visible {
446
+ outline: 2px solid var(--sp-focus);
447
+ outline-offset: 2px;
448
+ }
449
+
450
+ .sp-daystrip {
451
+ display: grid;
452
+ grid-template-columns: repeat(var(--_sp-day-count, 5), minmax(0, 1fr));
453
+ gap: var(--sp-gap);
454
+ margin-block-end: 1rem;
455
+ }
456
+
457
+ .sp-strip-day {
458
+ display: grid;
459
+ justify-items: center;
460
+ gap: 0.1rem;
461
+ min-inline-size: 0;
462
+ padding-block: 0.6rem 0.55rem;
463
+ padding-inline: 0.25rem;
464
+ border: 1px solid var(--sp-border);
465
+ border-radius: var(--sp-radius);
466
+ background: var(--sp-card-bg);
467
+ color: var(--sp-fg);
468
+ font: inherit;
469
+ cursor: pointer;
470
+ }
471
+
472
+ .sp-strip-day:hover {
473
+ background: var(--sp-hover);
474
+ }
475
+
476
+ .sp-strip-day[aria-pressed="true"] {
477
+ border-color: var(--sp-accent);
478
+ background: var(--sp-accent-soft);
479
+ }
480
+
481
+ .sp-strip-weekday {
482
+ color: var(--sp-muted);
483
+ font-size: 0.85rem;
484
+ }
485
+
486
+ .sp-strip-day[data-today] .sp-strip-weekday {
487
+ font-weight: 700;
488
+ }
489
+
490
+ .sp-strip-date {
491
+ font-size: 0.9rem;
492
+ }
493
+
494
+ .sp-strip-count {
495
+ max-inline-size: 100%;
496
+ color: var(--sp-muted);
497
+ font-size: 0.8rem;
498
+ text-align: center;
499
+ overflow-wrap: anywhere;
500
+ }
501
+
502
+ .sp-panel-header {
503
+ position: relative;
504
+ display: flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ gap: 0.5rem;
508
+ margin-block-end: 0.75rem;
509
+ text-align: center;
510
+ }
511
+
512
+ .sp-panel-title {
513
+ font-size: 1rem;
514
+ }
515
+
516
+ .sp-panel-slots {
517
+ display: grid;
518
+ grid-template-columns: repeat(var(--sp-slot-columns, 3), minmax(0, 1fr));
519
+ gap: var(--sp-gap);
520
+ }
521
+
522
+ /* Readable notice. Non-interactive: the control is the dot. Overflow is
523
+ structurally contained so it can never bleed into the next column. */
524
+ .sp-day-notice {
525
+ display: block;
526
+ box-sizing: border-box;
527
+ min-inline-size: 0;
528
+ max-inline-size: 100%;
529
+ overflow: hidden;
530
+ margin-block-end: 0.75rem;
531
+ padding: 0.75rem 1rem;
532
+ border-radius: var(--sp-radius);
533
+ background: var(--sp-hover);
534
+ text-align: center;
535
+ }
536
+
537
+ .sp-day-notice-label {
538
+ display: -webkit-box;
539
+ overflow: hidden;
540
+ overflow-wrap: anywhere;
541
+ -webkit-box-orient: vertical;
542
+ -webkit-line-clamp: 2;
543
+ margin-block-end: 0.25rem;
544
+ }
545
+
546
+ /* The description stays in the DOM in every projection; the layout decides
547
+ how much is revealed. Themes may override either rule. */
548
+ .sp-day-notice-description {
549
+ display: none;
550
+ min-inline-size: 0;
551
+ max-inline-size: 100%;
552
+ overflow-wrap: anywhere;
553
+ margin: 0;
554
+ color: var(--sp-muted);
555
+ font-size: 0.9rem;
556
+ }
557
+
558
+ slot-picker[layout="day"] .sp-day-notice-label {
559
+ display: block;
560
+ -webkit-line-clamp: unset;
561
+ }
562
+
563
+ slot-picker[layout="day"] .sp-day-notice-description {
564
+ display: block;
565
+ }
566
+
567
+ .sp-nav:focus-visible,
568
+ .sp-home:focus-visible,
569
+ .sp-more-button:focus-visible,
570
+ .sp-notice[data-day-index]:focus-visible,
571
+ .sp-strip-day:focus-visible {
572
+ outline: 2px solid var(--sp-focus);
573
+ outline-offset: 2px;
574
+ }
575
+
576
+ @media (forced-colors: active) {
577
+ .sp-slot {
578
+ border-color: ButtonText;
579
+ }
580
+
581
+ .sp-slot[aria-selected="true"] {
582
+ border-width: 2px;
583
+ }
584
+
585
+ .sp-strip-day[aria-pressed="true"] {
586
+ border-width: 2px;
587
+ border-color: ButtonText;
588
+ }
589
+
590
+ .sp-day-notice {
591
+ border: 1px solid ButtonText;
592
+ }
593
+
594
+ .sp-notice-dot {
595
+ background: CanvasText;
596
+ }
597
+ }