@mdbase-dev/ui 0.1.0-beta.125 → 0.1.0-beta.147

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 (77) hide show
  1. package/README.md +159 -0
  2. package/css/brand.css +10 -10
  3. package/css/collections.css +978 -0
  4. package/css/controls.css +220 -43
  5. package/css/feedback.css +20 -20
  6. package/css/fonts.css +2 -3
  7. package/css/palette.css +10 -10
  8. package/css/screens.css +58 -16
  9. package/css/tokens.css +43 -3
  10. package/dist/AppSwitcher.js +187 -33
  11. package/dist/Checkbox.d.ts +14 -0
  12. package/dist/Checkbox.js +32 -0
  13. package/dist/CommandPalette.d.ts +4 -2
  14. package/dist/CommandPalette.js +275 -103
  15. package/dist/Dialog.js +72 -25
  16. package/dist/Feedback.js +763 -229
  17. package/dist/FeedbackMarkup.d.ts +1 -1
  18. package/dist/FeedbackMarkup.js +326 -125
  19. package/dist/FeedbackVerification.js +115 -68
  20. package/dist/SaveNotice.js +71 -28
  21. package/dist/Select.js +183 -135
  22. package/dist/SelectList.js +59 -14
  23. package/dist/ThemeSelect.js +55 -4
  24. package/dist/apps.d.ts +1 -0
  25. package/dist/apps.js +50 -29
  26. package/dist/brand.js +251 -68
  27. package/dist/codemirror.js +116 -87
  28. package/dist/collections/CollectionGate.d.ts +52 -0
  29. package/dist/collections/CollectionGate.js +456 -0
  30. package/dist/collections/CollectionSaveWarning.d.ts +10 -0
  31. package/dist/collections/CollectionSaveWarning.js +28 -0
  32. package/dist/collections/CollectionSwitcher.d.ts +26 -0
  33. package/dist/collections/CollectionSwitcher.js +579 -0
  34. package/dist/collections/SetupReview.d.ts +9 -0
  35. package/dist/collections/SetupReview.js +175 -0
  36. package/dist/collections/copy.d.ts +100 -0
  37. package/dist/collections/copy.js +937 -0
  38. package/dist/collections/dialogs.d.ts +27 -0
  39. package/dist/collections/dialogs.js +169 -0
  40. package/dist/collections/model.d.ts +146 -0
  41. package/dist/collections/model.js +337 -0
  42. package/dist/collections/mount.d.ts +18 -0
  43. package/dist/collections/mount.js +56 -0
  44. package/dist/collections/parts.d.ts +86 -0
  45. package/dist/collections/parts.js +439 -0
  46. package/dist/collections/testing.d.ts +19 -0
  47. package/dist/collections/testing.js +39 -0
  48. package/dist/collections/use-collection-ui.d.ts +140 -0
  49. package/dist/collections/use-collection-ui.js +236 -0
  50. package/dist/collections.d.ts +19 -0
  51. package/dist/collections.js +13 -0
  52. package/dist/feedback-data.d.ts +13 -12
  53. package/dist/feedback-data.js +365 -168
  54. package/dist/flock.d.ts +63 -0
  55. package/dist/flock.js +140 -0
  56. package/dist/i18n.d.ts +6 -0
  57. package/dist/i18n.js +71 -0
  58. package/dist/locales/de/messages.json +1 -0
  59. package/dist/locales/en/messages.json +1 -0
  60. package/dist/locales/es/messages.json +1 -0
  61. package/dist/locales/fr/messages.json +1 -0
  62. package/dist/locales/it/messages.json +1 -0
  63. package/dist/locales/ja/messages.json +1 -0
  64. package/dist/locales/ko/messages.json +1 -0
  65. package/dist/locales/pt/messages.json +1 -0
  66. package/dist/locales/ru/messages.json +1 -0
  67. package/dist/locales/zh/messages.json +1 -0
  68. package/dist/mark-activity.js +82 -75
  69. package/dist/permission-selection.js +27 -17
  70. package/dist/popover.js +138 -130
  71. package/dist/screens.d.ts +20 -3
  72. package/dist/screens.js +275 -6
  73. package/dist/select-model.js +34 -28
  74. package/dist/text-diff.d.ts +1 -0
  75. package/dist/text-diff.js +106 -74
  76. package/dist/theme.js +34 -40
  77. package/package.json +53 -8
@@ -0,0 +1,978 @@
1
+ @import "./brand.css";
2
+ @import "./motion.css";
3
+ @import "./screens.css";
4
+
5
+ /*
6
+ * Shared collection screens (@mdbase-dev/ui/collections). Every rule reads
7
+ * private --_* properties defined below. Each one takes, in order: the public
8
+ * --mdbase-collections-* property, the app-ui token from tokens.css, then a
9
+ * built-in value, so collections.css renders on its own. Apps with their own
10
+ * design system map the public properties (anywhere up the tree, :root is
11
+ * fine) instead of overriding internals. The README lists them all.
12
+ */
13
+ .mdbase-collections {
14
+ /* Colour */
15
+ --_accent: var(--mdbase-collections-accent, var(--color-accent, oklch(47% 0.1 238)));
16
+ --_on-accent: var(--mdbase-collections-on-accent, var(--color-on-accent, oklch(98% 0.004 245)));
17
+ --_surface: var(--mdbase-collections-surface, var(--color-surface, oklch(99.5% 0.002 255)));
18
+ --_canvas: var(--mdbase-collections-canvas, var(--color-canvas, oklch(99.5% 0.002 255)));
19
+ --_text: var(--mdbase-collections-text, var(--color-text, oklch(21% 0.018 255)));
20
+ --_text-soft: var(--mdbase-collections-text-soft, var(--color-text-soft, oklch(50% 0.014 255)));
21
+ --_border: var(--mdbase-collections-border, var(--color-border-strong, oklch(82% 0.008 255)));
22
+ --_danger: var(--mdbase-collections-danger, var(--color-danger, oklch(50% 0.11 28)));
23
+ --_warning: var(--mdbase-collections-warning, var(--color-warning-text, oklch(43% 0.055 69)));
24
+ --_warning-edge: var(--mdbase-collections-warning-edge, var(--color-warning, oklch(60% 0.09 75)));
25
+ --_scrim: var(--mdbase-collections-scrim, var(--color-scrim, rgb(0 0 0 / 0.3)));
26
+ /*
27
+ * Mixes are in oklab, which has no hue: in oklch an achromatic surface
28
+ * written as oklch(L 0 0) carries hue 0 (red) into the mix and tints it pink.
29
+ */
30
+ --_subtle: color-mix(in oklab, var(--_text) 5%, var(--_surface));
31
+ --_current-bg: var(--mdbase-collections-current-bg, color-mix(in oklab, var(--_accent) 9%, var(--_surface)));
32
+ /* Type */
33
+ --_font-size: var(--mdbase-collections-font-size, var(--font-size-ui, 0.8125rem));
34
+ --_font-size-caption: var(--mdbase-collections-font-size-caption, var(--font-size-caption, 0.75rem));
35
+ --_font-size-section: var(--mdbase-collections-font-size-section, var(--font-size-section, 0.9375rem));
36
+ --_font-size-heading: var(--mdbase-collections-font-size-heading, var(--font-size-heading, 1.5rem));
37
+ --_weight-regular: var(--font-weight-regular, 400);
38
+ --_weight-medium: var(--font-weight-medium, 500);
39
+ --_weight-semibold: var(--mdbase-collections-font-weight-strong, var(--font-weight-semibold, 600));
40
+ /* Shape */
41
+ --_radius-sm: var(--mdbase-collections-radius-sm, var(--radius-sm, 4px));
42
+ --_radius: var(--mdbase-collections-radius, var(--radius-md, 8px));
43
+ --_radius-lg: var(--mdbase-collections-radius-lg, var(--radius-lg, 12px));
44
+ --_elevation-low: var(--mdbase-collections-elevation-low, var(--elevation-low, 0 4px 12px rgb(0 0 0 / 0.1)));
45
+ --_elevation-high: var(--mdbase-collections-elevation-high, var(--elevation-high, 0 12px 32px rgb(0 0 0 / 0.16)));
46
+ --_control: var(--mdbase-collections-control-height, 36px);
47
+ /* Motion */
48
+ --_ease: var(--ease-standard, ease);
49
+ --_fast: var(--motion-quick, 150ms);
50
+ --_spin: var(--motion-spin, 700ms);
51
+ color: var(--_text);
52
+ font-family: var(--mdbase-collections-font, var(--sans, system-ui, sans-serif));
53
+ font-size: var(--_font-size);
54
+ line-height: 1.45;
55
+ }
56
+
57
+ @media (prefers-reduced-motion: reduce) {
58
+ .mdbase-collections {
59
+ --_fast: var(--motion-quick, 0ms);
60
+ }
61
+ }
62
+
63
+ @media (pointer: coarse) {
64
+ .mdbase-collections {
65
+ --_control: var(--mdbase-collections-control-height, 44px);
66
+ }
67
+ }
68
+
69
+ .mdbase-collections *,
70
+ .mdbase-collections *::before,
71
+ .mdbase-collections *::after {
72
+ box-sizing: border-box;
73
+ }
74
+
75
+ .mdbase-collections-visually-hidden {
76
+ position: absolute;
77
+ width: 1px;
78
+ height: 1px;
79
+ overflow: hidden;
80
+ clip: rect(0 0 0 0);
81
+ white-space: nowrap;
82
+ }
83
+
84
+ /* Keep a known opening stage and its slow warning on separate lines. */
85
+ .mdbase-collections-lead,
86
+ .mdbase-collections .mdbase-opening-message small {
87
+ white-space: pre-line;
88
+ }
89
+
90
+ /* Gate: one column, heading, lead, the screen's own content, then the footer. */
91
+ .mdbase-collections-gate {
92
+ display: grid;
93
+ place-items: start center;
94
+ padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
95
+ }
96
+
97
+ .mdbase-collections-gate[data-layout="page"] {
98
+ min-height: 100dvh;
99
+ padding-top: max(10vh, 32px);
100
+ background: var(--_canvas);
101
+ }
102
+
103
+ .mdbase-collections-gate-body {
104
+ width: min(100%, 560px);
105
+ display: grid;
106
+ gap: 16px;
107
+ min-width: 0;
108
+ }
109
+
110
+ .mdbase-collections-brand {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 8px;
114
+ margin: 0;
115
+ color: var(--_text-soft);
116
+ font-weight: var(--_weight-semibold);
117
+ }
118
+
119
+ .mdbase-collections-brand-mark {
120
+ display: inline-flex;
121
+ width: 24px;
122
+ height: 24px;
123
+ }
124
+
125
+ .mdbase-collections-brand-mark > * {
126
+ width: 100%;
127
+ height: 100%;
128
+ }
129
+
130
+ .mdbase-collections-heading {
131
+ margin: 8px 0 0;
132
+ color: var(--_text);
133
+ font-size: var(--_font-size-heading);
134
+ font-weight: var(--_weight-semibold);
135
+ line-height: 1.2;
136
+ letter-spacing: -0.015em;
137
+ overflow-wrap: anywhere;
138
+ }
139
+
140
+ .mdbase-collections-gate[data-layout="panel"] .mdbase-collections-heading {
141
+ font-size: var(--_font-size-section);
142
+ }
143
+
144
+ /* Phase headings receive focus for context, not as interactive controls. */
145
+ :is(h1, h2).mdbase-collections-heading[tabindex="-1"]:focus,
146
+ :is(h1, h2).mdbase-collections-visually-hidden[tabindex="-1"]:focus {
147
+ outline: none;
148
+ }
149
+
150
+ .mdbase-collections-lead {
151
+ max-width: 52ch;
152
+ margin: 0;
153
+ color: var(--_text-soft);
154
+ font-size: var(--_font-size-section);
155
+ }
156
+
157
+ .mdbase-collections-actions {
158
+ display: flex;
159
+ flex-wrap: wrap;
160
+ align-items: center;
161
+ gap: 8px 12px;
162
+ }
163
+
164
+ .mdbase-collections-progress {
165
+ display: flex;
166
+ align-items: center;
167
+ gap: 10px;
168
+ margin: 0;
169
+ color: var(--_text-soft);
170
+ }
171
+
172
+ /* Buttons: one filled action per screen, tonal secondary, text-led quiet. */
173
+ .mdbase-collections-button {
174
+ display: inline-flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ gap: 8px;
178
+ min-height: var(--_control);
179
+ padding: 0 14px;
180
+ border: 1px solid var(--_border);
181
+ border-radius: var(--_radius);
182
+ color: var(--_text);
183
+ background: var(--_surface);
184
+ font: inherit;
185
+ font-weight: var(--_weight-medium);
186
+ text-decoration: none;
187
+ cursor: pointer;
188
+ transition: background var(--_fast) var(--_ease), border-color var(--_fast) var(--_ease);
189
+ }
190
+
191
+ .mdbase-collections-button:hover:not([aria-disabled="true"]) {
192
+ background: var(--_subtle);
193
+ }
194
+
195
+ .mdbase-collections-button.is-primary {
196
+ border-color: var(--_accent);
197
+ color: var(--_on-accent);
198
+ background: var(--_accent);
199
+ }
200
+
201
+ .mdbase-collections-button.is-primary:hover:not([aria-disabled="true"]) {
202
+ background: color-mix(in oklab, var(--_accent) 88%, var(--_text));
203
+ }
204
+
205
+ .mdbase-collections-button.is-quiet {
206
+ min-height: auto;
207
+ padding: 4px 2px;
208
+ border-color: transparent;
209
+ color: var(--_accent);
210
+ background: transparent;
211
+ }
212
+
213
+ .mdbase-collections-button.is-quiet:hover:not([aria-disabled="true"]) {
214
+ background: transparent;
215
+ text-decoration: underline;
216
+ }
217
+
218
+ .mdbase-collections-button.is-danger {
219
+ border-color: var(--_danger);
220
+ color: var(--_on-accent);
221
+ background: var(--_danger);
222
+ }
223
+
224
+ .mdbase-collections-button[aria-disabled="true"] {
225
+ cursor: default;
226
+ opacity: 0.6;
227
+ }
228
+
229
+ .mdbase-collections-button svg {
230
+ width: 16px;
231
+ height: 16px;
232
+ fill: none;
233
+ stroke: currentColor;
234
+ stroke-width: 1.6;
235
+ stroke-linecap: round;
236
+ }
237
+
238
+ .mdbase-collections-link {
239
+ color: var(--_accent);
240
+ text-underline-offset: 2px;
241
+ }
242
+
243
+ .mdbase-collections-button:focus-visible,
244
+ .mdbase-collections-link:focus-visible,
245
+ .mdbase-collections-row:focus-visible,
246
+ .mdbase-collections-more:focus-visible,
247
+ .mdbase-collections-trigger:focus-visible,
248
+ .mdbase-collections-menu-item:focus-visible,
249
+ .mdbase-collections-field:focus-visible {
250
+ outline: 2px solid var(--_accent);
251
+ outline-offset: 2px;
252
+ }
253
+
254
+ /* A problem and its fix in one block, with the fix inside. */
255
+ .mdbase-collections-notice {
256
+ display: grid;
257
+ gap: 10px;
258
+ padding: 12px 14px;
259
+ border: 1px solid var(--_border);
260
+ border-left-width: 3px;
261
+ border-radius: var(--_radius);
262
+ background: var(--_surface);
263
+ }
264
+
265
+ .mdbase-collections-notice[data-tone="warning"] {
266
+ border-left-color: var(--_warning-edge);
267
+ }
268
+
269
+ .mdbase-collections-notice[data-tone="error"] {
270
+ border-left-color: var(--_danger);
271
+ }
272
+
273
+ .mdbase-collections-notice[data-tone="info"] {
274
+ border-left-color: var(--_accent);
275
+ }
276
+
277
+ .mdbase-collections-notice.is-inline {
278
+ padding: 8px 12px;
279
+ }
280
+
281
+ .mdbase-collections-notice.is-banner {
282
+ grid-template-columns: minmax(0, 1fr) auto;
283
+ align-items: center;
284
+ border-width: 0 0 1px;
285
+ border-radius: 0;
286
+ }
287
+
288
+ .mdbase-collections-notice-copy {
289
+ display: grid;
290
+ gap: 2px;
291
+ min-width: 0;
292
+ }
293
+
294
+ .mdbase-collections-notice-title {
295
+ margin: 0;
296
+ font-weight: var(--_weight-semibold);
297
+ }
298
+
299
+ .mdbase-collections-notice-message {
300
+ margin: 0;
301
+ color: var(--_text-soft);
302
+ overflow-wrap: anywhere;
303
+ }
304
+
305
+ .mdbase-collections-notice-actions {
306
+ display: flex;
307
+ flex-wrap: wrap;
308
+ gap: 8px;
309
+ }
310
+
311
+ /* Collections are a list, not buttons among actions. */
312
+ .mdbase-collections-section {
313
+ display: grid;
314
+ gap: 8px;
315
+ }
316
+
317
+ .mdbase-collections-section-title {
318
+ margin: 0;
319
+ color: var(--_text-soft);
320
+ font-size: var(--_font-size-caption);
321
+ font-weight: var(--_weight-semibold);
322
+ }
323
+
324
+ .mdbase-collections-list {
325
+ display: grid;
326
+ margin: 0;
327
+ padding: 0;
328
+ overflow: hidden;
329
+ border: 1px solid var(--_border);
330
+ border-radius: var(--_radius);
331
+ list-style: none;
332
+ }
333
+
334
+ .mdbase-collections-list > .mdbase-collections-item + .mdbase-collections-item {
335
+ border-top: 1px solid var(--_border);
336
+ }
337
+
338
+ .mdbase-collections-item {
339
+ display: flex;
340
+ align-items: center;
341
+ gap: 4px;
342
+ min-width: 0;
343
+ padding-right: 4px;
344
+ background: var(--_surface);
345
+ }
346
+
347
+ .mdbase-collections-row {
348
+ display: flex;
349
+ flex: 1 1 auto;
350
+ align-items: center;
351
+ gap: 10px;
352
+ min-width: 0;
353
+ min-height: calc(var(--_control) + 12px);
354
+ padding: 8px 10px;
355
+ border: 0;
356
+ border-radius: var(--_radius-sm);
357
+ color: inherit;
358
+ background: transparent;
359
+ font: inherit;
360
+ text-align: start;
361
+ cursor: pointer;
362
+ }
363
+
364
+ .mdbase-collections-row:hover:not([aria-disabled="true"]) {
365
+ background: var(--_subtle);
366
+ }
367
+
368
+ .mdbase-collections-row[aria-disabled="true"] {
369
+ cursor: default;
370
+ }
371
+
372
+ .mdbase-collections-row[aria-disabled="true"] .mdbase-collections-row-name {
373
+ color: var(--_text-soft);
374
+ }
375
+
376
+ .mdbase-collections-row[aria-checked="true"],
377
+ .mdbase-collections-row[aria-current="true"] {
378
+ background: var(--_current-bg);
379
+ }
380
+
381
+ .mdbase-collections-mark {
382
+ display: grid;
383
+ flex: 0 0 auto;
384
+ place-items: center;
385
+ width: 28px;
386
+ height: 28px;
387
+ border-radius: var(--_radius-sm);
388
+ color: oklch(36% 0.08 var(--mdbase-collections-hue));
389
+ background: oklch(92% 0.045 var(--mdbase-collections-hue));
390
+ font-size: var(--_font-size-caption);
391
+ font-weight: 700;
392
+ letter-spacing: 0.02em;
393
+ }
394
+
395
+ :root[data-theme="dark"] .mdbase-collections-mark {
396
+ color: oklch(88% 0.06 var(--mdbase-collections-hue));
397
+ background: oklch(34% 0.06 var(--mdbase-collections-hue));
398
+ }
399
+
400
+ @media (prefers-color-scheme: dark) {
401
+ :root:not([data-theme="light"]) .mdbase-collections-mark {
402
+ color: oklch(88% 0.06 var(--mdbase-collections-hue));
403
+ background: oklch(34% 0.06 var(--mdbase-collections-hue));
404
+ }
405
+ }
406
+
407
+ .mdbase-collections-row-copy {
408
+ display: grid;
409
+ flex: 1 1 auto;
410
+ grid-template-columns: minmax(0, 1fr);
411
+ gap: 1px;
412
+ min-width: 0;
413
+ }
414
+
415
+ /* Rows are buttons, and hosts often style `button > span` to one ellipsized
416
+ * line (a navigation rail, a toolbar). A list row's copy still wraps. */
417
+ .mdbase-collections .mdbase-collections-row-copy,
418
+ .mdbase-collections .mdbase-collections-row-copy > span {
419
+ overflow: visible;
420
+ text-overflow: clip;
421
+ white-space: normal;
422
+ }
423
+
424
+ /* Names wrap; they are never cut to an ellipsis in a list. */
425
+ .mdbase-collections-row-name {
426
+ font-weight: var(--_weight-semibold);
427
+ overflow-wrap: anywhere;
428
+ }
429
+
430
+ .mdbase-collections-row-hint,
431
+ .mdbase-collections-row-meta,
432
+ .mdbase-collections-row-secondary,
433
+ .mdbase-collections-row-detail {
434
+ color: var(--_text-soft);
435
+ font-size: var(--_font-size-caption);
436
+ font-weight: var(--_weight-regular);
437
+ }
438
+
439
+ .mdbase-collections-row-secondary,
440
+ .mdbase-collections-row-detail {
441
+ overflow-wrap: anywhere;
442
+ }
443
+
444
+ .mdbase-collections-check {
445
+ width: 16px;
446
+ height: 16px;
447
+ flex: 0 0 auto;
448
+ fill: none;
449
+ stroke: var(--_accent);
450
+ stroke-width: 2;
451
+ stroke-linecap: round;
452
+ stroke-linejoin: round;
453
+ }
454
+
455
+ .mdbase-collections-more {
456
+ display: inline-grid;
457
+ flex: 0 0 auto;
458
+ place-items: center;
459
+ width: var(--_control);
460
+ height: var(--_control);
461
+ border: 0;
462
+ border-radius: var(--_radius-sm);
463
+ color: var(--_text-soft);
464
+ background: transparent;
465
+ cursor: pointer;
466
+ }
467
+
468
+ .mdbase-collections-more:hover,
469
+ .mdbase-collections-more[aria-expanded="true"] {
470
+ color: var(--_text);
471
+ background: var(--_subtle);
472
+ }
473
+
474
+ .mdbase-collections-more svg {
475
+ width: 16px;
476
+ height: 16px;
477
+ fill: currentColor;
478
+ stroke: currentColor;
479
+ stroke-width: 1.6;
480
+ stroke-linecap: round;
481
+ }
482
+
483
+ .mdbase-collections-menu {
484
+ position: fixed;
485
+ inset: auto;
486
+ min-width: 200px;
487
+ margin: 0;
488
+ padding: 4px;
489
+ border: 1px solid var(--_border);
490
+ border-radius: var(--_radius);
491
+ color: var(--_text);
492
+ background: var(--_surface);
493
+ box-shadow: var(--_elevation-low);
494
+ }
495
+
496
+ .mdbase-collections-menu-item {
497
+ display: flex;
498
+ align-items: center;
499
+ width: 100%;
500
+ min-height: var(--_control);
501
+ padding: 0 10px;
502
+ border: 0;
503
+ border-radius: var(--_radius-sm);
504
+ color: inherit;
505
+ background: transparent;
506
+ font: inherit;
507
+ text-align: start;
508
+ cursor: pointer;
509
+ }
510
+
511
+ .mdbase-collections-menu-item:hover:not(:disabled),
512
+ .mdbase-collections-menu-item:focus-visible {
513
+ background: var(--_subtle);
514
+ }
515
+
516
+ .mdbase-collections-menu-item.is-danger {
517
+ color: var(--_danger);
518
+ }
519
+
520
+ .mdbase-collections-menu-item:disabled {
521
+ color: var(--_text-soft);
522
+ cursor: default;
523
+ }
524
+
525
+ .mdbase-collections-footer {
526
+ display: flex;
527
+ flex-wrap: wrap;
528
+ align-items: center;
529
+ gap: 8px 16px;
530
+ padding-top: 12px;
531
+ border-top: 1px solid var(--_border);
532
+ color: var(--_text-soft);
533
+ }
534
+
535
+ /* The app's own actions lead the footer. */
536
+ .mdbase-collections-footer-extra {
537
+ display: inline-flex;
538
+ flex-wrap: wrap;
539
+ align-items: center;
540
+ gap: 8px 12px;
541
+ min-width: 0;
542
+ }
543
+
544
+ .mdbase-collections-account {
545
+ display: inline-flex;
546
+ flex-wrap: wrap;
547
+ align-items: center;
548
+ gap: 4px 10px;
549
+ min-width: 0;
550
+ }
551
+
552
+ .mdbase-collections-account-label {
553
+ overflow-wrap: anywhere;
554
+ }
555
+
556
+ /* OpeningScreen owns the loading presentation; the gate retains its actions. */
557
+ .mdbase-collections-gate .mdbase-opening {
558
+ min-height: 160px;
559
+ height: auto;
560
+ background: transparent;
561
+ }
562
+
563
+ .mdbase-collections-gate .mdbase-opening-message {
564
+ color: var(--_text-soft);
565
+ --mark-accent: var(--_accent);
566
+ }
567
+
568
+ .mdbase-collections-gate .mdbase-opening-message p {
569
+ font-size: var(--_font-size);
570
+ }
571
+
572
+ .mdbase-collections-gate .mdbase-opening-message small {
573
+ color: var(--_text-soft);
574
+ font-size: var(--_font-size-caption);
575
+ }
576
+
577
+ .mdbase-collections-spinner {
578
+ width: 16px;
579
+ height: 16px;
580
+ flex: 0 0 auto;
581
+ border: 2px solid color-mix(in oklab, var(--_text-soft) 35%, transparent);
582
+ border-top-color: var(--_accent);
583
+ border-radius: 50%;
584
+ animation: mdbase-collections-spin var(--_spin) linear infinite;
585
+ }
586
+
587
+ @keyframes mdbase-collections-spin {
588
+ to { transform: rotate(360deg); }
589
+ }
590
+
591
+ @media (prefers-reduced-motion: reduce) {
592
+ .mdbase-collections-spinner {
593
+ animation-duration: 2.4s;
594
+ }
595
+ }
596
+
597
+ /* Panel: the switcher's list inline (settings dialogs, write-first apps). */
598
+ .mdbase-collections-panel {
599
+ display: grid;
600
+ gap: 10px;
601
+ min-width: 0;
602
+ }
603
+
604
+ /* Setup review. */
605
+ .mdbase-collections-setup {
606
+ display: grid;
607
+ gap: 12px;
608
+ }
609
+
610
+ .mdbase-collections-setup-summary {
611
+ margin: 0;
612
+ }
613
+
614
+ .mdbase-collections-setup-section {
615
+ display: grid;
616
+ gap: 4px;
617
+ }
618
+
619
+ .mdbase-collections-setup-section h3 {
620
+ margin: 0;
621
+ color: var(--_text-soft);
622
+ font-size: var(--_font-size-caption);
623
+ font-weight: var(--_weight-semibold);
624
+ }
625
+
626
+ .mdbase-collections-setup-list {
627
+ display: grid;
628
+ gap: 4px;
629
+ max-height: 40vh;
630
+ margin: 0;
631
+ padding: 8px 12px 8px 28px;
632
+ overflow: auto;
633
+ border: 1px solid var(--_border);
634
+ border-radius: var(--_radius);
635
+ overflow-wrap: anywhere;
636
+ }
637
+
638
+ /* Switcher trigger: the name wraps to two lines, and only a longer one is cut
639
+ * short; the full name is always in the trigger's label and title. */
640
+ .mdbase-collections-switcher {
641
+ display: inline-flex;
642
+ min-width: 0;
643
+ max-width: 100%;
644
+ }
645
+
646
+ .mdbase-collections-trigger {
647
+ display: inline-flex;
648
+ align-items: center;
649
+ gap: 6px;
650
+ min-width: 0;
651
+ max-width: 100%;
652
+ min-height: var(--_control);
653
+ padding: 2px 8px;
654
+ border: 1px solid transparent;
655
+ border-radius: var(--_radius-sm);
656
+ color: inherit;
657
+ background: transparent;
658
+ font: inherit;
659
+ cursor: pointer;
660
+ transition: background var(--_fast) var(--_ease), border-color var(--_fast) var(--_ease);
661
+ }
662
+
663
+ .mdbase-collections-trigger:hover,
664
+ .mdbase-collections-trigger[aria-expanded="true"] {
665
+ border-color: var(--_border);
666
+ background: var(--_surface);
667
+ }
668
+
669
+ .mdbase-collections-trigger-icon {
670
+ display: inline-grid;
671
+ flex: 0 0 auto;
672
+ place-items: center;
673
+ width: 20px;
674
+ height: 20px;
675
+ }
676
+
677
+ .mdbase-collections-trigger-icon > svg,
678
+ .mdbase-collections-trigger-icon > img {
679
+ width: 100%;
680
+ height: 100%;
681
+ }
682
+
683
+ .mdbase-collections-trigger-icon > .mdbase-collections-mark {
684
+ width: 20px;
685
+ height: 20px;
686
+ font-size: 0.625rem;
687
+ }
688
+
689
+ .mdbase-collections .mdbase-collections-trigger-name {
690
+ display: -webkit-box;
691
+ min-width: 0;
692
+ overflow: hidden;
693
+ font-weight: var(--_weight-semibold);
694
+ line-height: 1.2;
695
+ text-align: start;
696
+ text-overflow: ellipsis;
697
+ white-space: normal;
698
+ overflow-wrap: anywhere;
699
+ -webkit-box-orient: vertical;
700
+ -webkit-line-clamp: 2;
701
+ line-clamp: 2;
702
+ }
703
+
704
+ .mdbase-collections-trigger-role {
705
+ flex: 0 0 auto;
706
+ color: var(--_text-soft);
707
+ font-size: var(--_font-size-caption);
708
+ }
709
+
710
+ .mdbase-collections-chevron,
711
+ .mdbase-collections-glyph {
712
+ width: 14px;
713
+ height: 14px;
714
+ flex: 0 0 auto;
715
+ fill: none;
716
+ stroke: var(--_text-soft);
717
+ stroke-width: 1.6;
718
+ stroke-linecap: round;
719
+ stroke-linejoin: round;
720
+ transition: transform var(--_fast) var(--_ease);
721
+ }
722
+
723
+ .mdbase-collections-glyph {
724
+ width: 18px;
725
+ height: 18px;
726
+ }
727
+
728
+ .mdbase-collections-trigger[aria-expanded="true"] .mdbase-collections-chevron {
729
+ transform: rotate(180deg);
730
+ }
731
+
732
+ @media (max-width: 680px) {
733
+ .mdbase-collections-switcher[data-variant="full"] .mdbase-collections-trigger-role {
734
+ display: none;
735
+ }
736
+ }
737
+
738
+ .mdbase-collections-popover {
739
+ position: fixed;
740
+ inset: auto;
741
+ z-index: 80;
742
+ margin: 0;
743
+ padding: 6px;
744
+ overflow: auto;
745
+ border: 1px solid var(--_border);
746
+ border-radius: var(--_radius-lg);
747
+ outline: 0;
748
+ color: var(--_text);
749
+ background: var(--_surface);
750
+ box-shadow: var(--_elevation-high);
751
+ overscroll-behavior: contain;
752
+ }
753
+
754
+ .mdbase-collections-switcher-content {
755
+ display: grid;
756
+ gap: 6px;
757
+ min-width: 0;
758
+ }
759
+
760
+ .mdbase-collections-switcher-header {
761
+ display: grid;
762
+ gap: 2px;
763
+ padding: 6px 8px;
764
+ }
765
+
766
+ .mdbase-collections-eyebrow {
767
+ color: var(--_text-soft);
768
+ font-size: var(--_font-size-caption);
769
+ font-weight: 700;
770
+ }
771
+
772
+ .mdbase-collections-switcher-current {
773
+ display: flex;
774
+ flex-wrap: wrap;
775
+ align-items: center;
776
+ gap: 4px 8px;
777
+ overflow-wrap: anywhere;
778
+ }
779
+
780
+ .mdbase-collections-chip {
781
+ padding: 1px 6px;
782
+ border: 1px solid var(--_border);
783
+ border-radius: var(--_radius-lg);
784
+ color: var(--_text-soft);
785
+ font-size: var(--_font-size-caption);
786
+ }
787
+
788
+ /* A Private collection's label: the lock and the word, never colour alone. */
789
+ .mdbase-collections-private {
790
+ display: inline-flex;
791
+ align-items: center;
792
+ gap: 3px;
793
+ vertical-align: 1px;
794
+ font-weight: var(--_weight-regular);
795
+ white-space: nowrap;
796
+ }
797
+
798
+ .mdbase-collections-private svg {
799
+ width: 11px;
800
+ height: 11px;
801
+ fill: none;
802
+ stroke: currentColor;
803
+ stroke-width: 1.5;
804
+ stroke-linejoin: round;
805
+ }
806
+
807
+ .mdbase-collections-field {
808
+ width: 100%;
809
+ min-height: var(--_control);
810
+ padding: 0 10px;
811
+ border: 1px solid var(--_border);
812
+ border-radius: var(--_radius-sm);
813
+ color: var(--_text);
814
+ background: var(--_canvas);
815
+ font: inherit;
816
+ }
817
+
818
+ .mdbase-collections-filter {
819
+ margin: 0 2px;
820
+ width: auto;
821
+ }
822
+
823
+ .mdbase-collections-switcher-lists {
824
+ display: grid;
825
+ gap: 10px;
826
+ }
827
+
828
+ .mdbase-collections-switcher-section {
829
+ display: grid;
830
+ gap: 4px;
831
+ }
832
+
833
+ .mdbase-collections-switcher-section > .mdbase-collections-section-title {
834
+ padding: 0 8px;
835
+ }
836
+
837
+ .mdbase-collections-switcher-list {
838
+ display: grid;
839
+ gap: 1px;
840
+ }
841
+
842
+ .mdbase-collections-switcher-list .mdbase-collections-item {
843
+ padding-right: 0;
844
+ background: transparent;
845
+ }
846
+
847
+ .mdbase-collections-switcher-list .mdbase-collections-row {
848
+ min-height: var(--_control);
849
+ padding: 6px 8px;
850
+ }
851
+
852
+ .mdbase-collections-empty {
853
+ margin: 4px 8px;
854
+ color: var(--_text-soft);
855
+ }
856
+
857
+ .mdbase-collections-switcher-actions {
858
+ display: flex;
859
+ flex-wrap: wrap;
860
+ align-items: center;
861
+ justify-content: space-between;
862
+ gap: 4px 12px;
863
+ padding: 6px 8px 2px;
864
+ border-top: 1px solid var(--_border);
865
+ }
866
+
867
+ .mdbase-collections-switcher-actions .is-add {
868
+ padding-left: 0;
869
+ }
870
+
871
+ .mdbase-collections-switcher-footer {
872
+ padding: 6px 8px 2px;
873
+ border-top: 1px solid var(--_border);
874
+ color: var(--_text-soft);
875
+ }
876
+
877
+ /* Narrow screens: the switcher is a bottom sheet. */
878
+ .mdbase-collections-sheet {
879
+ width: 100%;
880
+ max-width: 100%;
881
+ max-height: 85dvh;
882
+ margin: auto 0 0;
883
+ padding: 0;
884
+ border: 0;
885
+ border-radius: var(--_radius-lg) var(--_radius-lg) 0 0;
886
+ color: var(--_text);
887
+ background: var(--_surface);
888
+ }
889
+
890
+ .mdbase-collections-sheet::backdrop {
891
+ background: var(--_scrim);
892
+ }
893
+
894
+ .mdbase-collections-sheet-body {
895
+ display: grid;
896
+ gap: 6px;
897
+ padding: 8px 12px max(12px, env(safe-area-inset-bottom));
898
+ }
899
+
900
+ .mdbase-collections-sheet-header {
901
+ display: flex;
902
+ align-items: center;
903
+ justify-content: space-between;
904
+ padding: 0 0 0 8px;
905
+ }
906
+
907
+ .mdbase-collections-sheet-title {
908
+ font-weight: var(--_weight-semibold);
909
+ }
910
+
911
+ /* Confirmations. */
912
+ .mdbase-collections-dialog {
913
+ width: min(100% - 32px, 440px);
914
+ padding: 20px;
915
+ border: 1px solid var(--_border);
916
+ border-radius: var(--_radius-lg);
917
+ color: var(--_text);
918
+ background: var(--_surface);
919
+ box-shadow: var(--_elevation-high);
920
+ }
921
+
922
+ .mdbase-collections-dialog::backdrop {
923
+ background: var(--_scrim);
924
+ }
925
+
926
+ .mdbase-collections-dialog-title {
927
+ margin: 0 0 8px;
928
+ font-size: var(--_font-size-section);
929
+ overflow-wrap: anywhere;
930
+ }
931
+
932
+ .mdbase-collections-dialog-body {
933
+ display: grid;
934
+ gap: 10px;
935
+ color: var(--_text-soft);
936
+ }
937
+
938
+ .mdbase-collections-dialog-body p {
939
+ margin: 0;
940
+ }
941
+
942
+ .mdbase-collections-dialog-body form {
943
+ display: grid;
944
+ gap: 6px;
945
+ }
946
+
947
+ .mdbase-collections-field-label {
948
+ color: var(--_text);
949
+ }
950
+
951
+ .mdbase-collections-dialog-error {
952
+ color: var(--_danger);
953
+ }
954
+
955
+ .mdbase-collections-dialog-actions {
956
+ display: flex;
957
+ flex-wrap: wrap;
958
+ justify-content: flex-end;
959
+ gap: 8px;
960
+ margin-top: 18px;
961
+ }
962
+
963
+ @media (max-width: 479.98px) {
964
+ .mdbase-collections-gate .mdbase-collections-actions > .mdbase-collections-button:not(.is-quiet) {
965
+ flex: 1 1 100%;
966
+ }
967
+
968
+ .mdbase-collections-dialog-actions > .mdbase-collections-button {
969
+ flex: 1 1 auto;
970
+ }
971
+ }
972
+
973
+ .mdbase-collections-save-warning {
974
+ color: var(--mdbase-collections-text-soft, var(--color-text-soft, inherit));
975
+ font-size: var(--mdbase-collections-font-size-caption, var(--font-size-caption, 0.75rem));
976
+ line-height: 1.4;
977
+ overflow-wrap: anywhere;
978
+ }