@tonycodes-ui/mortar 0.0.0-stage → 0.12.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 (107) hide show
  1. package/AGENTS.md +10 -0
  2. package/CHANGELOG.md +268 -0
  3. package/CONTRIBUTING.md +60 -0
  4. package/DESIGN.md +51 -0
  5. package/LICENSE +21 -0
  6. package/README.md +155 -2
  7. package/TESTING.md +83 -0
  8. package/baseline-policy.json +16 -0
  9. package/bin/mortar.mjs +258 -0
  10. package/catalog.json +9900 -0
  11. package/cli/audit.mjs +943 -0
  12. package/cli/data.mjs +176 -0
  13. package/cli/mcp.mjs +216 -0
  14. package/cli/migrations.mjs +128 -0
  15. package/cli/packet.mjs +267 -0
  16. package/cli/search.mjs +246 -0
  17. package/cli/tools.mjs +229 -0
  18. package/design-principles.json +30 -0
  19. package/dist/agent-data.json +1 -0
  20. package/dist/application.d.ts +340 -0
  21. package/dist/application.js +240 -0
  22. package/dist/auth.d.ts +121 -0
  23. package/dist/auth.js +97 -0
  24. package/dist/brand.d.ts +69 -0
  25. package/dist/brand.js +266 -0
  26. package/dist/calendar.d.ts +75 -0
  27. package/dist/calendar.js +310 -0
  28. package/dist/choice.d.ts +36 -0
  29. package/dist/choice.js +36 -0
  30. package/dist/composer.d.ts +28 -0
  31. package/dist/composer.js +47 -0
  32. package/dist/display.d.ts +136 -0
  33. package/dist/display.js +75 -0
  34. package/dist/docs.d.ts +145 -0
  35. package/dist/docs.js +141 -0
  36. package/dist/ecommerce.d.ts +261 -0
  37. package/dist/ecommerce.js +177 -0
  38. package/dist/feedback.d.ts +80 -0
  39. package/dist/feedback.js +98 -0
  40. package/dist/foundation.d.ts +42 -0
  41. package/dist/foundation.js +121 -0
  42. package/dist/heading.d.ts +5 -0
  43. package/dist/heading.js +9 -0
  44. package/dist/icons.d.ts +50 -0
  45. package/dist/icons.js +70 -0
  46. package/dist/illustration.d.ts +47 -0
  47. package/dist/illustration.js +47 -0
  48. package/dist/index.d.ts +36 -0
  49. package/dist/index.js +18 -0
  50. package/dist/inspection.d.ts +24 -0
  51. package/dist/inspection.js +14 -0
  52. package/dist/internal.d.ts +514 -0
  53. package/dist/internal.js +332 -0
  54. package/dist/layout.d.ts +107 -0
  55. package/dist/layout.js +66 -0
  56. package/dist/marketing-sections.d.ts +161 -0
  57. package/dist/marketing-sections.js +58 -0
  58. package/dist/marketing.d.ts +277 -0
  59. package/dist/marketing.js +163 -0
  60. package/dist/navigation.d.ts +35 -0
  61. package/dist/navigation.js +44 -0
  62. package/dist/primitives.d.ts +258 -0
  63. package/dist/primitives.js +244 -0
  64. package/dist/showcase.d.ts +29 -0
  65. package/dist/showcase.js +10 -0
  66. package/dist/workspace.d.ts +80 -0
  67. package/dist/workspace.js +48 -0
  68. package/docs/agents.md +127 -0
  69. package/docs/auth-flows.md +71 -0
  70. package/docs/migrating-to-0.6.md +94 -0
  71. package/docs/theming.md +170 -0
  72. package/package.json +94 -4
  73. package/skills/mortar/SKILL.md +36 -0
  74. package/src/application.css +1487 -0
  75. package/src/application.tsx +1413 -0
  76. package/src/auth.tsx +452 -0
  77. package/src/brand.ts +335 -0
  78. package/src/calendar.css +468 -0
  79. package/src/calendar.tsx +868 -0
  80. package/src/choice.tsx +240 -0
  81. package/src/composer.tsx +158 -0
  82. package/src/data.css +690 -0
  83. package/src/display.tsx +452 -0
  84. package/src/docs.css +704 -0
  85. package/src/docs.tsx +737 -0
  86. package/src/ecommerce.css +810 -0
  87. package/src/ecommerce.tsx +1033 -0
  88. package/src/feedback.tsx +388 -0
  89. package/src/foundation.css +1867 -0
  90. package/src/foundation.tsx +227 -0
  91. package/src/heading.ts +13 -0
  92. package/src/icons.tsx +237 -0
  93. package/src/illustration.tsx +169 -0
  94. package/src/index.ts +233 -0
  95. package/src/inspection.tsx +91 -0
  96. package/src/internal.tsx +700 -0
  97. package/src/layout.tsx +342 -0
  98. package/src/marketing-sections.tsx +621 -0
  99. package/src/marketing.css +2579 -0
  100. package/src/marketing.tsx +1235 -0
  101. package/src/navigation.tsx +118 -0
  102. package/src/overlays.css +350 -0
  103. package/src/primitives.tsx +1135 -0
  104. package/src/showcase.tsx +120 -0
  105. package/src/tokens.css +449 -0
  106. package/src/workspace.tsx +333 -0
  107. package/styles.css +56 -0
package/src/data.css ADDED
@@ -0,0 +1,690 @@
1
+ /* Data: tables, lists and description lists.
2
+ Every rule sits in @layer components, so equal-specificity rules resolve by source
3
+ order. styles.css loads tokens, foundation, overlays, application, data, calendar,
4
+ marketing, docs and ecommerce in that order; inside a file each component keeps
5
+ one section, ordered base, then variants and states, then media and container
6
+ queries, except where that would change which equal-specificity rule wins. */
7
+ @layer components {
8
+ /* == Tables: DataTable, Table and table state == */
9
+ /* One table base for DataTable, Table, PlanComparison and prose tables. Each sets
10
+ its cell padding; DataTable and Table follow density through --m-row-pad. */
11
+ .m-data-table {
12
+ overflow: hidden;
13
+ min-width: 0;
14
+ --m-cell-pad-y: var(--m-row-pad);
15
+ --m-cell-pad-x: var(--m-row-pad);
16
+ }
17
+ .m-table-toolbar {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ flex-wrap: wrap;
22
+ gap: 12px;
23
+ padding: 12px;
24
+ border-bottom: 1px solid var(--m-line);
25
+ font-size: 13px;
26
+ }
27
+ .m-table-scroll {
28
+ overflow-x: auto;
29
+ }
30
+ .m-table {
31
+ --m-cell-pad-y: calc(var(--m-row-pad) - 4px);
32
+ --m-cell-pad-x: var(--m-row-pad);
33
+ }
34
+ :is(.m-data-table, .m-table, .m-comparison) table,
35
+ .m-prose
36
+ table:where(:not([data-m-component], .m-prose [data-m-component] *)) {
37
+ border-collapse: collapse;
38
+ font-size: 14px;
39
+ text-align: left;
40
+ }
41
+ :is(.m-data-table, .m-table, .m-comparison) table {
42
+ width: 100%;
43
+ }
44
+ .m-data-table table {
45
+ font-size: var(--m-font-size);
46
+ }
47
+ :is(.m-data-table, .m-table, .m-comparison) :is(th, td),
48
+ .m-prose
49
+ :is(th, td):where(:not([data-m-component], .m-prose [data-m-component] *)) {
50
+ padding: var(--m-cell-pad-y) var(--m-cell-pad-x);
51
+ border-bottom: 1px solid var(--m-line);
52
+ }
53
+ .m-data-table :is(th, td) {
54
+ white-space: nowrap;
55
+ }
56
+ .m-table :is(th, td),
57
+ .m-prose
58
+ :is(th, td):where(:not([data-m-component], .m-prose [data-m-component] *)) {
59
+ vertical-align: top;
60
+ }
61
+ :is(.m-data-table, .m-table) thead th,
62
+ .m-prose
63
+ thead
64
+ th:where(:not([data-m-component], .m-prose [data-m-component] *)) {
65
+ color: var(--m-muted);
66
+ font-size: 12px;
67
+ font-weight: var(--m-weight-semibold);
68
+ }
69
+ .m-data-table thead th {
70
+ background: var(--m-paper);
71
+ }
72
+ .m-table thead th,
73
+ .m-prose
74
+ thead
75
+ th:where(:not([data-m-component], .m-prose [data-m-component] *)) {
76
+ white-space: nowrap;
77
+ }
78
+ :is(.m-data-table, .m-table) tbody th {
79
+ font-weight: var(--m-weight-semibold);
80
+ }
81
+ .m-data-table tr:last-child :is(th, td) {
82
+ border-bottom: 0;
83
+ }
84
+ .m-table-state {
85
+ padding: 32px;
86
+ color: var(--m-muted);
87
+ }
88
+ .m-sort-button {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ gap: 6px;
92
+ width: 100%;
93
+ padding: var(--m-cell-pad-y) var(--m-cell-pad-x);
94
+ color: inherit;
95
+ font: inherit;
96
+ text-align: inherit;
97
+ --m-icon-size: 12px;
98
+ }
99
+ .m-sort-button svg {
100
+ flex-shrink: 0;
101
+ fill: none;
102
+ stroke: currentColor;
103
+ stroke-width: 1.5;
104
+ stroke-linecap: round;
105
+ stroke-linejoin: round;
106
+ }
107
+ .m-sort-button svg path {
108
+ opacity: 0.35;
109
+ }
110
+ .m-data-table colgroup .m-table-select-col {
111
+ width: 44px;
112
+ }
113
+ .m-truncate {
114
+ display: block;
115
+ overflow: hidden;
116
+ text-overflow: ellipsis;
117
+ white-space: nowrap;
118
+ }
119
+ .m-row-link {
120
+ color: inherit;
121
+ text-decoration: none;
122
+ }
123
+ .m-row-link::after {
124
+ content: "";
125
+ position: absolute;
126
+ inset: 0;
127
+ }
128
+ .m-table-footer {
129
+ padding: 10px 12px;
130
+ border-top: 1px solid var(--m-line);
131
+ }
132
+ .m-table,
133
+ .m-prose
134
+ table:where(:not([data-m-component], .m-prose [data-m-component] *)) {
135
+ min-width: 0;
136
+ overflow-x: auto;
137
+ border: 1px solid var(--m-line);
138
+ border-radius: var(--m-radius-lg);
139
+ background: var(--m-surface);
140
+ }
141
+ .m-table caption:not(.m-sr-only) {
142
+ padding: 12px 14px 0;
143
+ text-align: left;
144
+ font-weight: var(--m-weight-semibold);
145
+ }
146
+ :is(
147
+ .m-table tbody tr:last-child :is(th, td),
148
+ .m-prose
149
+ tbody
150
+ tr:last-child
151
+ :is(th, td):where(:not([data-m-component], .m-prose [data-m-component] *))
152
+ ) {
153
+ border-bottom: 0;
154
+ }
155
+ :is(.m-data-table, .m-table) .m-table-group th {
156
+ padding-block: 6px;
157
+ border-top: 1px solid var(--m-line);
158
+ border-bottom: 1px solid var(--m-line);
159
+ background: var(--m-sunken);
160
+ color: var(--m-ink);
161
+ font-size: 12px;
162
+ font-weight: var(--m-weight-semibold);
163
+ text-align: left;
164
+ }
165
+ /* The column header row already draws the line above the first group. */
166
+ :is(.m-data-table, .m-table) thead + tbody > .m-table-group th {
167
+ border-top: 0;
168
+ }
169
+ .m-data-table[data-density="compact"] {
170
+ --m-cell-pad-y: 6px;
171
+ --m-cell-pad-x: 10px;
172
+ }
173
+ :is(.m-data-table, .m-table) [data-align="end"] {
174
+ text-align: right;
175
+ font-variant-numeric: tabular-nums;
176
+ }
177
+ .m-data-table [data-selected] {
178
+ background: var(--m-selected);
179
+ }
180
+ /* --m-selected is close to --m-sunken, so selection also gets a non-colour cue. */
181
+ .m-data-table tr[data-selected] > :first-child {
182
+ box-shadow: inset 3px 0 0 var(--m-primary);
183
+ }
184
+ .m-data-table thead th[aria-sort] {
185
+ padding: 0;
186
+ }
187
+ [data-align="end"] > .m-sort-button {
188
+ justify-content: flex-end;
189
+ }
190
+ .m-sort-button:hover {
191
+ color: var(--m-ink);
192
+ }
193
+ th[aria-sort="ascending"] .m-sort-button,
194
+ th[aria-sort="descending"] .m-sort-button {
195
+ color: var(--m-ink);
196
+ }
197
+ .m-sort-button svg path[data-active] {
198
+ opacity: 1;
199
+ }
200
+ .m-table-scroll[data-sticky] {
201
+ overflow: auto;
202
+ }
203
+ .m-table-scroll[data-sticky] thead th {
204
+ position: sticky;
205
+ top: 0;
206
+ z-index: 1;
207
+ box-shadow: inset 0 -1px 0 var(--m-line);
208
+ }
209
+ .m-data-table [data-truncate] {
210
+ max-width: 0;
211
+ }
212
+ .m-data-table tr[data-linked] {
213
+ position: relative;
214
+ }
215
+ .m-data-table tr[data-linked]:hover {
216
+ background: var(--m-sunken);
217
+ }
218
+ .m-row-link:hover {
219
+ text-decoration: underline;
220
+ }
221
+ .m-row-link:focus-visible {
222
+ outline: none;
223
+ }
224
+ .m-row-link:focus-visible::after {
225
+ outline: 2px solid var(--m-focus);
226
+ outline-offset: -2px;
227
+ }
228
+ /* Cell actions remain independent of the stretched row navigation link. */
229
+ .m-data-table
230
+ tr[data-linked]
231
+ :is(
232
+ button,
233
+ input,
234
+ select,
235
+ textarea,
236
+ summary,
237
+ a:not(.m-row-link),
238
+ [role="button"],
239
+ [tabindex]
240
+ ) {
241
+ position: relative;
242
+ z-index: 1;
243
+ }
244
+ .m-data-table[data-density="compact"] table {
245
+ font-size: 13px;
246
+ }
247
+ /* Zero specificity: hover and selection always win over stripes. */
248
+ :where(
249
+ :is(.m-data-table, .m-table)[data-striped]
250
+ tbody
251
+ tr:nth-child(even of :not(.m-table-group))
252
+ ) {
253
+ background: var(--m-sunken);
254
+ }
255
+ .m-data-table[data-density="compact"] .m-table-group th {
256
+ padding-block: 4px;
257
+ }
258
+ @media (max-width: 640px) {
259
+ /* Narrow screens scroll the table instead of collapsing truncated columns. */
260
+ .m-data-table [data-truncate] {
261
+ max-width: none;
262
+ }
263
+ .m-truncate {
264
+ max-width: 14rem;
265
+ }
266
+ }
267
+
268
+ /* == StackedList == */
269
+ .m-stacked-list {
270
+ overflow: hidden;
271
+ }
272
+ .m-stacked-list > header {
273
+ display: flex;
274
+ align-items: center;
275
+ justify-content: space-between;
276
+ gap: 12px;
277
+ padding: 14px 18px;
278
+ border-bottom: 1px solid var(--m-line);
279
+ }
280
+ .m-stacked-list > :where(header) > .m-stacked-title {
281
+ font-size: 15px;
282
+ font-weight: var(--m-weight-semibold);
283
+ }
284
+ .m-stacked-list li {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 12px;
288
+ padding: var(--m-row-pad) 18px;
289
+ border-bottom: 1px solid var(--m-line);
290
+ }
291
+ .m-stacked-list li:last-child {
292
+ border-bottom: 0;
293
+ }
294
+ .m-stacked-list li > :is(a, div):first-child {
295
+ display: flex;
296
+ align-items: center;
297
+ gap: 12px;
298
+ flex: 1;
299
+ min-width: 0;
300
+ color: inherit;
301
+ text-decoration: none;
302
+ }
303
+ .m-stacked-text {
304
+ min-width: 0;
305
+ line-height: 1.3;
306
+ }
307
+ .m-stacked-text strong {
308
+ display: block;
309
+ font-size: var(--m-font-size);
310
+ }
311
+ .m-stacked-text span {
312
+ display: block;
313
+ font-size: 12px;
314
+ color: var(--m-muted);
315
+ overflow: hidden;
316
+ text-overflow: ellipsis;
317
+ }
318
+ /* clip, not hidden: hidden makes the list a scroll container and stops headings sticking. */
319
+ .m-stacked-list:has(> .m-stacked-group) {
320
+ overflow: clip;
321
+ }
322
+ .m-stacked-group-heading {
323
+ position: sticky;
324
+ /* Set --m-sticky-top to the height of a fixed app header so headings stop below it. */
325
+ top: var(--m-sticky-top, 0px);
326
+ z-index: 1;
327
+ margin: 0;
328
+ padding: 6px 18px;
329
+ border-bottom: 1px solid var(--m-line);
330
+ background: var(--m-sunken);
331
+ color: var(--m-secondary);
332
+ font-size: 12px;
333
+ font-weight: var(--m-weight-semibold);
334
+ }
335
+ .m-stacked-list > .m-stacked-group:not(:last-child) li:last-child {
336
+ border-bottom: 1px solid var(--m-line);
337
+ }
338
+ /* A header with only an action keeps the action at the end. */
339
+ .m-stacked-action {
340
+ display: flex;
341
+ gap: 8px;
342
+ margin-inline-start: auto;
343
+ }
344
+ /* StackedList second column and link chevrons. */
345
+ .m-stacked-list:has(.m-stacked-meta) {
346
+ container: m-stacked-list / inline-size;
347
+ }
348
+ .m-stacked-list li > :is(a, div):first-child:has(> .m-stacked-meta) {
349
+ flex-wrap: wrap;
350
+ }
351
+ .m-stacked-list
352
+ li
353
+ > :is(a, div):has(> :is(.m-stacked-meta, .m-stacked-chevron))
354
+ > .m-stacked-text {
355
+ flex: 1 1 0;
356
+ }
357
+ .m-stacked-meta {
358
+ display: grid;
359
+ flex-shrink: 0;
360
+ gap: 2px;
361
+ max-width: 50%;
362
+ color: var(--m-ink);
363
+ font-size: 13px;
364
+ line-height: 1.3;
365
+ text-align: end;
366
+ }
367
+ .m-stacked-meta > :not(:first-child) {
368
+ color: var(--m-muted);
369
+ font-size: 12px;
370
+ }
371
+ .m-stacked-chevron {
372
+ display: inline-flex;
373
+ flex-shrink: 0;
374
+ color: var(--m-muted);
375
+ }
376
+ .m-stacked-chevron svg {
377
+ width: 18px;
378
+ height: 18px;
379
+ }
380
+ @container m-stacked-list (max-width: 480px) {
381
+ .m-stacked-meta {
382
+ order: 3;
383
+ flex-basis: 100%;
384
+ max-width: none;
385
+ text-align: start;
386
+ }
387
+ }
388
+
389
+ /* == GridList == */
390
+ .m-grid-list {
391
+ display: grid;
392
+ grid-template-columns: repeat(var(--m-grid-columns, 3), minmax(0, 1fr));
393
+ gap: 20px;
394
+ }
395
+ .m-grid-list > li {
396
+ position: relative;
397
+ display: flex;
398
+ flex-direction: column;
399
+ min-width: 0;
400
+ overflow: hidden;
401
+ }
402
+ .m-grid-list-cover {
403
+ aspect-ratio: 16 / 9;
404
+ background: var(--m-sunken);
405
+ border-bottom: 1px solid var(--m-line);
406
+ }
407
+ .m-grid-list-cover img {
408
+ display: block;
409
+ width: 100%;
410
+ height: 100%;
411
+ object-fit: cover;
412
+ }
413
+ .m-grid-list-body {
414
+ display: flex;
415
+ flex: 1;
416
+ align-items: flex-start;
417
+ gap: 12px;
418
+ min-width: 0;
419
+ padding: 16px;
420
+ }
421
+ .m-grid-list-media {
422
+ display: inline-flex;
423
+ flex-shrink: 0;
424
+ }
425
+ .m-grid-list-text {
426
+ min-width: 0;
427
+ }
428
+ .m-grid-list-title {
429
+ margin: 0;
430
+ font-size: var(--m-font-size);
431
+ font-weight: var(--m-weight-semibold);
432
+ overflow-wrap: anywhere;
433
+ }
434
+ .m-grid-list-title a {
435
+ color: inherit;
436
+ text-decoration: none;
437
+ }
438
+ /* The title link covers the card; actions sit above it so they stay clickable. */
439
+ .m-grid-list-title a::after {
440
+ content: "";
441
+ position: absolute;
442
+ inset: 0;
443
+ }
444
+ .m-grid-list-text p {
445
+ margin: 2px 0 0;
446
+ color: var(--m-muted);
447
+ font-size: 13px;
448
+ }
449
+ .m-grid-list-meta {
450
+ display: flex;
451
+ flex-wrap: wrap;
452
+ gap: 6px;
453
+ margin-top: 8px;
454
+ }
455
+ .m-grid-list-actions {
456
+ position: relative;
457
+ z-index: 1;
458
+ display: flex;
459
+ flex-wrap: wrap;
460
+ gap: 8px;
461
+ padding: 12px 16px;
462
+ border-top: 1px solid var(--m-line);
463
+ }
464
+ .m-grid-list-details {
465
+ margin: 0;
466
+ padding: 0 16px 8px;
467
+ font-size: 13px;
468
+ }
469
+ .m-grid-list-details > div {
470
+ display: flex;
471
+ justify-content: space-between;
472
+ gap: 16px;
473
+ padding: 8px 0;
474
+ border-top: 1px solid var(--m-line);
475
+ }
476
+ .m-grid-list-details dt {
477
+ color: var(--m-muted);
478
+ }
479
+ .m-grid-list-details dd {
480
+ margin: 0;
481
+ color: var(--m-ink);
482
+ font-weight: var(--m-weight-medium);
483
+ text-align: right;
484
+ min-width: 0;
485
+ overflow-wrap: anywhere;
486
+ }
487
+ /* Links and controls in a card's media, meta and details sit above the
488
+ stretched title link, so they stay clickable. */
489
+ :is(.m-grid-list-media, .m-grid-list-meta, .m-grid-list-details)
490
+ :is(a, button, input, select, textarea, summary, [tabindex]) {
491
+ position: relative;
492
+ z-index: 1;
493
+ }
494
+ .m-grid-list[data-columns="2"] {
495
+ --m-grid-columns: 2;
496
+ }
497
+ .m-grid-list[data-columns="4"] {
498
+ --m-grid-columns: 4;
499
+ }
500
+ .m-grid-list > li:has(.m-grid-list-text a:focus-visible) {
501
+ outline: 2px solid var(--m-focus);
502
+ outline-offset: var(--m-focus-offset);
503
+ }
504
+ .m-grid-list-text a:focus-visible {
505
+ outline: none;
506
+ }
507
+ .m-grid-list > li:has(a:hover) {
508
+ border-color: var(--m-line-strong);
509
+ }
510
+ .m-grid-list[data-actions="split"] .m-grid-list-actions {
511
+ flex-wrap: nowrap;
512
+ gap: 0;
513
+ padding: 0;
514
+ }
515
+ .m-grid-list[data-actions="split"] .m-grid-list-actions > * {
516
+ display: inline-flex;
517
+ flex: 1 1 0;
518
+ align-items: center;
519
+ justify-content: center;
520
+ gap: 8px;
521
+ min-width: 0;
522
+ min-height: 44px;
523
+ margin: 0;
524
+ padding: 8px 12px;
525
+ border: 0;
526
+ border-radius: 0;
527
+ background: transparent;
528
+ box-shadow: none;
529
+ color: var(--m-ink);
530
+ font-size: 13px;
531
+ font-weight: var(--m-weight-semibold);
532
+ text-decoration: none;
533
+ }
534
+ .m-grid-list[data-actions="split"] .m-grid-list-actions > * + * {
535
+ border-left: 1px solid var(--m-line);
536
+ }
537
+ .m-grid-list[data-actions="split"] .m-grid-list-actions > :hover {
538
+ background: var(--m-sunken);
539
+ }
540
+ .m-grid-list[data-actions="split"] .m-grid-list-actions > :focus-visible {
541
+ outline: 2px solid var(--m-focus);
542
+ outline-offset: -2px;
543
+ }
544
+ .m-grid-list[data-actions="split"] .m-grid-list-actions svg {
545
+ flex-shrink: 0;
546
+ color: var(--m-muted);
547
+ }
548
+ @media (max-width: 900px) {
549
+ .m-grid-list:is([data-columns], :not([data-columns])) {
550
+ --m-grid-columns: 2;
551
+ }
552
+ }
553
+ @media (max-width: 560px) {
554
+ .m-grid-list:is([data-columns], :not([data-columns])) {
555
+ --m-grid-columns: 1;
556
+ }
557
+ }
558
+
559
+ /* == DescriptionList == */
560
+ .m-description-list {
561
+ container: m-description-list / inline-size;
562
+ min-width: 0;
563
+ }
564
+ .m-description-heading {
565
+ padding-bottom: 14px;
566
+ }
567
+ .m-description-heading .m-description-title {
568
+ margin: 0;
569
+ font-size: 15px;
570
+ font-weight: var(--m-weight-semibold);
571
+ }
572
+ .m-description-heading p {
573
+ margin: 2px 0 0;
574
+ color: var(--m-muted);
575
+ font-size: 13px;
576
+ }
577
+ .m-description-list dl {
578
+ margin: 0;
579
+ border-top: 1px solid var(--m-line);
580
+ }
581
+ .m-description-list dl > div {
582
+ display: grid;
583
+ grid-template-columns: minmax(0, 1fr);
584
+ gap: 2px 16px;
585
+ padding: var(--m-row-pad) 0;
586
+ border-bottom: 1px solid var(--m-line);
587
+ }
588
+ .m-description-list dt {
589
+ color: var(--m-ink);
590
+ font-size: var(--m-font-size);
591
+ font-weight: var(--m-weight-semibold);
592
+ }
593
+ .m-description-list dd {
594
+ margin: 0;
595
+ min-width: 0;
596
+ color: var(--m-secondary);
597
+ font-size: var(--m-font-size);
598
+ overflow-wrap: anywhere;
599
+ }
600
+ .m-description-list dl > div > :is(dt, dd) {
601
+ grid-column: 1;
602
+ }
603
+ .m-description-list dl > div > .m-description-action {
604
+ grid-column: 2;
605
+ grid-row: 1 / span 2;
606
+ align-self: center;
607
+ }
608
+ .m-description-list dl > div[data-action] {
609
+ grid-template-columns: minmax(0, 1fr) auto;
610
+ }
611
+ /* DescriptionList striped: shaded alternate rows instead of dividers. */
612
+ .m-description-list[data-variant="striped"] dl {
613
+ border-top: 0;
614
+ }
615
+ .m-description-list[data-variant="striped"] dl > div {
616
+ padding-inline: 16px;
617
+ border-bottom: 0;
618
+ border-radius: var(--m-radius);
619
+ }
620
+ .m-description-list[data-variant="striped"] dl > div:nth-child(odd) {
621
+ background: var(--m-sunken);
622
+ }
623
+ @container m-description-list (min-width: 560px) {
624
+ /* Rows share one set of tracks so details align whether or not a row has an action. */
625
+ .m-description-list:not([data-layout]) dl {
626
+ display: grid;
627
+ grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
628
+ }
629
+ .m-description-list:not([data-layout]) dl > div {
630
+ grid-column: 1 / -1;
631
+ grid-template-columns: subgrid;
632
+ align-items: baseline;
633
+ }
634
+ .m-description-list:not([data-layout]) dl > div > :is(dt, dd) {
635
+ grid-row: 1;
636
+ grid-column: 2;
637
+ }
638
+ .m-description-list:not([data-layout]) dl > div > dt {
639
+ grid-column: 1;
640
+ }
641
+ .m-description-list:not([data-layout]) dl > div > .m-description-action {
642
+ grid-column: 3;
643
+ align-self: baseline;
644
+ }
645
+ }
646
+
647
+ /* == AttachmentList == */
648
+ .m-attachments {
649
+ border: 1px solid var(--m-line);
650
+ border-radius: var(--m-radius);
651
+ }
652
+ .m-attachments li {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 12px;
656
+ padding: 10px 14px;
657
+ border-bottom: 1px solid var(--m-line);
658
+ font-size: var(--m-font-size);
659
+ }
660
+ .m-attachments li:last-child {
661
+ border-bottom: 0;
662
+ }
663
+ .m-attachment-icon {
664
+ display: inline-flex;
665
+ flex-shrink: 0;
666
+ color: var(--m-muted);
667
+ --m-icon-size: 18px;
668
+ }
669
+ .m-attachment-text {
670
+ display: flex;
671
+ flex: 1;
672
+ flex-wrap: wrap;
673
+ gap: 2px 10px;
674
+ min-width: 0;
675
+ }
676
+ .m-attachment-name {
677
+ overflow: hidden;
678
+ color: var(--m-ink);
679
+ text-overflow: ellipsis;
680
+ white-space: nowrap;
681
+ }
682
+ .m-attachment-size {
683
+ color: var(--m-muted);
684
+ }
685
+ .m-attachments a {
686
+ flex-shrink: 0;
687
+ color: var(--m-link);
688
+ font-weight: var(--m-weight-semibold);
689
+ }
690
+ }