baseline-foundry 0.1.3 → 0.1.4

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 (43) hide show
  1. package/README.md +568 -552
  2. package/config/experiments/ibm-plex-engine-smoke.json +115 -115
  3. package/config/experiments/ubuntu-engine-smoke.json +115 -115
  4. package/config/foundation-theme.json +110 -110
  5. package/config/tiers/app.json +116 -116
  6. package/config/tiers/documentation.json +116 -116
  7. package/config/tiers/editorial.json +116 -116
  8. package/config/tiers/os.json +116 -116
  9. package/dist/baseline-grid-overlay.js +43 -43
  10. package/dist/css-app-tier.js +73 -73
  11. package/dist/css-components/article-pagination.js +140 -140
  12. package/dist/css-components/button-actions.js +161 -161
  13. package/dist/css-components/cards-options.js +176 -176
  14. package/dist/css-components/chip-badge-status.js +158 -158
  15. package/dist/css-components/content-card.js +490 -490
  16. package/dist/css-components/control-row.js +14 -14
  17. package/dist/css-components/cta-figure-aspect.js +120 -120
  18. package/dist/css-components/document-navigation.js +390 -390
  19. package/dist/css-components/editorial-content.js +42 -42
  20. package/dist/css-components/icon.js +72 -72
  21. package/dist/css-components/interactive-feedback.js +217 -217
  22. package/dist/css-components/interactive-tables.js +155 -155
  23. package/dist/css-components/legacy-navigation.d.ts +9 -0
  24. package/dist/css-components/legacy-navigation.js +763 -0
  25. package/dist/css-components/linked-logo-site-layout.js +177 -177
  26. package/dist/css-components/list-tree.js +94 -94
  27. package/dist/css-components/logo-media.js +201 -201
  28. package/dist/css-components/navigation-layout.js +144 -144
  29. package/dist/css-components/panel.js +144 -144
  30. package/dist/css-components/search-box-and-filter.js +263 -263
  31. package/dist/css-components/sites-editorial-ports.js +243 -243
  32. package/dist/css-components/sites-foundation.js +146 -146
  33. package/dist/css-components/sites-rich-lists.js +344 -344
  34. package/dist/css-components/static-content-ports.js +182 -182
  35. package/dist/css-components/tab-section.js +82 -82
  36. package/dist/css-components/table.js +75 -75
  37. package/dist/css-components/tabs-choice-breadcrumbs.js +303 -303
  38. package/dist/css-components/tiered-list-equal-height-row.js +271 -271
  39. package/dist/css-components.js +1791 -2542
  40. package/dist/css-grid.js +172 -172
  41. package/dist/css.js +240 -240
  42. package/docs/publishing.md +30 -13
  43. package/package.json +119 -108
@@ -16,349 +16,349 @@
16
16
  * margins and baseline compensation in every tier.
17
17
  */
18
18
  export function sitesRichListsCss() {
19
- return `/* ------------------------------------------------------------------ */
20
- /* Sites rich lists — structural slots around existing BF primitives. */
21
- /* ------------------------------------------------------------------ */
22
-
23
- :where(.bf-theme) :where(.bf-rich-list) {
24
- container-name: bf-rich-list;
25
- container-type: inline-size;
26
- min-inline-size: 0;
27
- padding-block-end: calc(var(--bf-section-space) / 2);
28
- }
29
-
30
- :where(.bf-theme) :where(.bf-rich-list.is-shallow) {
31
- padding-block-end: var(--bf-section-space-shallow);
32
- }
33
-
34
- :where(.bf-theme) :where(.bf-rich-list.is-deep) {
35
- padding-block-end: calc(var(--bf-section-space-deep) / 2);
36
- }
37
-
38
- :where(.bf-theme) :where(.bf-rich-list-layout) {
39
- display: grid;
40
- grid-template-columns: minmax(0, 1fr);
41
- min-inline-size: 0;
42
- }
43
-
44
- :where(.bf-theme) :where(.bf-rich-list-rule) {
45
- grid-column: 1 / -1;
46
- order: -2;
47
- }
48
-
49
- :where(.bf-theme) :where(.bf-rich-list-header, .bf-rich-list-support, .bf-rich-list-content, .bf-rich-list-media, .bf-rich-list-list-slot, .bf-rich-list-cta) {
50
- min-inline-size: 0;
51
- overflow-wrap: anywhere;
52
- }
53
-
54
- @media (width >= 64.75rem) {
55
- :where(.bf-theme) :where(.bf-rich-list:not(.is-shallow)) {
56
- padding-block-end: var(--bf-section-space);
57
- }
58
-
59
- :where(.bf-theme) :where(.bf-rich-list.is-deep) {
60
- padding-block-end: var(--bf-section-space-deep);
61
- }
62
- }
63
-
64
- /* ------------------------------------------------------------------ */
65
- /* Horizontal: the full composition remains stacked. The 50/50 variant */
66
- /* places title and support in equal logical rails at the large split. */
67
- /* ------------------------------------------------------------------ */
68
-
69
- :where(.bf-theme) :where(.bf-rich-list.is-horizontal) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-visual, .bf-rich-list-header, .bf-rich-list-support, .bf-rich-list-list-slot, .bf-rich-list-cta-rule) {
70
- grid-column: 1 / -1;
71
- }
72
-
73
- :where(.bf-theme) :where(.bf-rich-list-visual) {
74
- min-inline-size: 0;
75
- overflow: hidden;
76
- }
77
-
78
- :where(.bf-theme) :where(.bf-rich-list-visual > :where(img, picture, svg, video, canvas)) {
79
- block-size: auto;
80
- display: block;
81
- inline-size: 100%;
82
- max-inline-size: 100%;
83
- }
84
-
85
- /* A full-width ratio inside a fluid Sites rail otherwise leaves the next
86
- heading on a fractional pixel. The visual alone absorbs the trailing
87
- compensation; semantic children retain their own margins unchanged. */
88
- @supports (block-size: calc-size(auto, round(up, size, 1px))) {
89
- :where(.bf-theme) :where(.bf-rich-list-visual > .bf-aspect) {
90
- block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
91
- }
92
- }
93
-
94
- :where(.bf-theme) :where(.bf-rich-list-list-slot) {
95
- container-name: bf-rich-horizontal-items;
96
- container-type: inline-size;
97
- }
98
-
99
- :where(.bf-theme) :where(.bf-rich-list-list) {
100
- display: grid;
101
- grid-template-columns: minmax(0, 1fr);
102
- list-style: none;
103
- margin: 0;
104
- min-inline-size: 0;
105
- padding: 0;
106
- }
107
-
108
- /* Vanilla gives every horizontal-list row a continuous leading divider. */
109
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item {
110
- margin: 0;
111
- padding-block: var(--bf-space-1) var(--bf-space-2);
112
- position: relative;
113
- }
114
-
115
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after {
116
- background: var(--bf-color-border-low-contrast);
117
- block-size: var(--bf-border-width);
118
- content: "";
119
- inset-block-start: 0;
120
- inset-inline-start: 0;
121
- inline-size: 100%;
122
- position: absolute;
123
- }
124
-
125
- /* Prefixes are logical here even though the shared list predates BF's
126
- logical-property rule. This keeps ticks, bullets and numbers RTL-safe. */
127
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:is(.is-ticked, .is-crossed) {
128
- padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
129
- }
130
-
131
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:is(.is-ticked, .is-crossed)::before {
132
- inset: auto;
133
- inset-inline-start: 0;
134
- inset-block-start: calc(var(--bf-body-nudge-start) + var(--bf-space-1));
135
- }
136
-
137
- :where(.bf-theme) :where(.bf-rich-list-list.is-bulleted) > :where(.bf-list-item) {
138
- padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
139
- }
140
-
141
- :where(.bf-theme) :where(.bf-rich-list-list.is-bulleted) > :where(.bf-list-item)::before {
142
- color: var(--bf-color-text-default);
143
- content: "•";
144
- inline-size: var(--bf-leading-icon-size);
145
- inset-block-start: var(--bf-space-1);
146
- inset-inline-start: 0;
147
- position: absolute;
148
- text-align: center;
149
- }
150
-
151
- :where(.bf-theme) :where(ol.bf-rich-list-list) {
152
- counter-reset: bf-rich-horizontal-counter;
153
- }
154
-
155
- :where(.bf-theme) :where(ol.bf-rich-list-list) > :where(.bf-list-item) {
156
- counter-increment: bf-rich-horizontal-counter;
157
- padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
158
- }
159
-
160
- :where(.bf-theme) :where(ol.bf-rich-list-list) > :where(.bf-list-item)::before {
161
- color: var(--bf-color-text-default);
162
- content: counter(bf-rich-horizontal-counter) ".";
163
- inline-size: var(--bf-leading-icon-size);
164
- inset-block-start: var(--bf-space-1);
165
- inset-inline-start: 0;
166
- position: absolute;
167
- text-align: end;
168
- }
169
-
170
- /* Vanilla's list measures are content-derived: one column below 66ch, two
171
- from 66ch, and four from 100ch. Pseudo-rules span the complete row. */
172
- @container bf-rich-horizontal-items (width >= 66ch) {
173
- :where(.bf-theme) :where(.bf-rich-list-list) {
174
- column-gap: var(--bf-grid-gap-inline);
175
- grid-template-columns: repeat(2, minmax(0, 1fr));
176
- }
177
-
178
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after {
179
- content: none;
180
- }
181
-
182
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(2n + 1)::after {
183
- content: "";
184
- inline-size: calc(200% + var(--bf-grid-gap-inline));
185
- }
186
- }
187
-
188
- @container bf-rich-horizontal-items (width >= 100ch) {
189
- :where(.bf-theme) :where(.bf-rich-list-list) {
190
- grid-template-columns: repeat(4, minmax(0, 1fr));
191
- }
192
-
193
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after,
194
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(2n + 1)::after {
195
- content: none;
196
- }
197
-
198
- :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(4n + 1)::after {
199
- content: "";
200
- inline-size: calc(400% + (var(--bf-grid-gap-inline) * 3));
201
- }
202
- }
203
-
204
- @container bf-rich-list (width >= 64.75rem) {
205
- :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) {
206
- column-gap: var(--bf-grid-gap-inline);
207
- grid-template-columns: repeat(2, minmax(0, 1fr));
208
- }
209
-
210
- :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-header) {
211
- grid-column: 1;
212
- }
213
-
214
- :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-support) {
215
- grid-column: 2;
216
- }
217
-
218
- :where(.bf-theme) :where(.bf-rich-list.is-horizontal) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-cta) {
219
- grid-column: 2;
220
- }
221
- }
222
-
223
- /* ------------------------------------------------------------------ */
224
- /* Vertical: a rich media object, not a Jinja content-block adapter. */
225
- /* ------------------------------------------------------------------ */
226
-
227
- :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-rule) {
228
- grid-column: 1 / -1;
229
- }
230
-
231
- :where(.bf-theme) :where(.bf-rich-list.is-vertical) :where(.bf-rich-list-media) {
232
- container-type: inline-size;
233
- padding-block-end: var(--bf-section-space-shallow);
234
- }
235
-
236
- :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) :where(.bf-rich-list-media) {
237
- order: -1;
238
- }
239
-
240
- :where(.bf-theme) :where(.bf-rich-list-media-frame) {
241
- aspect-ratio: 3 / 2;
242
- display: block;
243
- inline-size: 100%;
244
- max-inline-size: 100%;
245
- overflow: hidden;
246
- position: relative;
247
- }
248
-
249
- /* The media object deliberately stretches across fluid 1/2 and 2/3 ratios.
250
- Snap that resulting block, rather than resetting content spacing, so each
251
- tier's baseline survives both portrait and landscape allocations. */
252
- @supports (block-size: calc-size(auto, round(up, size, 1px))) {
253
- :where(.bf-theme) :where(.bf-rich-list-media-frame) {
254
- block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
255
- }
256
- }
257
-
258
- :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-3-2) :where(.bf-rich-list-media-frame) {
259
- aspect-ratio: 3 / 2;
260
- }
261
-
262
- :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-16-9) :where(.bf-rich-list-media-frame),
263
- :where(.bf-theme) :where(.bf-rich-list-media.is-video) :where(.bf-rich-list-media-frame) {
264
- aspect-ratio: 16 / 9;
265
- }
266
-
267
- :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-square) :where(.bf-rich-list-media-frame) {
268
- aspect-ratio: 1 / 1;
269
- }
270
-
271
- :where(.bf-theme) :where(.bf-rich-list-media > .bf-rich-list-media-frame > :where(img, picture, svg, video, canvas, iframe)) {
272
- block-size: 100%;
273
- border: 0;
274
- display: block;
275
- inline-size: 100%;
276
- max-inline-size: 100%;
277
- object-fit: cover;
278
- }
279
-
280
- :where(.bf-theme) :where(.bf-rich-list-media > .bf-rich-list-media-frame > :where(picture) > :where(img)) {
281
- block-size: 100%;
282
- display: block;
283
- inline-size: 100%;
284
- object-fit: cover;
285
- }
286
-
287
- :where(.bf-theme) :where(.bf-rich-list-media.is-contain > .bf-rich-list-media-frame > :where(img, svg, video, canvas)),
288
- :where(.bf-theme) :where(.bf-rich-list-media.is-contain > .bf-rich-list-media-frame > :where(picture) > :where(img)) {
289
- object-fit: contain;
290
- }
291
-
292
- /* Auto height has no shallow media wrapper in Vanilla. At narrow widths it
293
- remains a normal 3:2 frame; at the wide split it stretches with the content
294
- rail, clamped between the equivalent 16:9 and 2:3 heights. */
295
- :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) {
296
- padding-block-end: 0;
297
- }
298
-
299
- @container bf-rich-list (width >= 64.75rem) {
300
- :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) {
301
- align-items: stretch;
302
- column-gap: var(--bf-grid-gap-inline);
303
- grid-template-columns: repeat(2, minmax(0, 1fr));
304
- }
305
-
306
- :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-content) {
307
- grid-column: 1;
308
- grid-row: 2;
309
- }
310
-
311
- :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-media) {
312
- grid-column: 2;
313
- grid-row: 2;
314
- order: 0;
315
- }
316
-
317
- :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-content) {
318
- grid-column: 2;
319
- }
320
-
321
- :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-media) {
322
- grid-column: 1;
323
- }
324
-
325
- :where(.bf-theme) :where(.bf-rich-list-media.is-wide-16-9) :where(.bf-rich-list-media-frame) {
326
- aspect-ratio: 16 / 9;
327
- }
328
-
329
- :where(.bf-theme) :where(.bf-rich-list-media.is-wide-3-2) :where(.bf-rich-list-media-frame) {
330
- aspect-ratio: 3 / 2;
331
- }
332
-
333
- :where(.bf-theme) :where(.bf-rich-list-media.is-wide-square) :where(.bf-rich-list-media-frame) {
334
- aspect-ratio: 1 / 1;
335
- }
336
-
337
- :where(.bf-theme) :where(.bf-rich-list-media.is-wide-2-3) :where(.bf-rich-list-media-frame) {
338
- aspect-ratio: 2 / 3;
339
- }
340
-
341
- :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) :where(.bf-rich-list-media-frame) {
342
- aspect-ratio: auto;
343
- block-size: 100%;
344
- max-block-size: 150cqi;
345
- min-block-size: 56.25cqi;
346
- }
347
-
348
- @supports (min-block-size: round(up, 1px, 1px)) {
349
- :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) :where(.bf-rich-list-media-frame) {
350
- max-block-size: round(down, 150cqi, var(--bf-baseline));
351
- min-block-size: round(up, 56.25cqi, var(--bf-baseline));
352
- }
353
- }
354
-
355
- /* Vanilla's auto-height image is absolutely positioned inside the clamped
356
- frame. Removing intrinsic media from track sizing lets the content rail
357
- determine the shared row before the 16:9/2:3 clamps are applied. */
358
- :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height > .bf-rich-list-media-frame > :where(img, picture, svg, video, canvas, iframe)) {
359
- inset: 0;
360
- position: absolute;
361
- }
362
- }
19
+ return `/* ------------------------------------------------------------------ */
20
+ /* Sites rich lists — structural slots around existing BF primitives. */
21
+ /* ------------------------------------------------------------------ */
22
+
23
+ :where(.bf-theme) :where(.bf-rich-list) {
24
+ container-name: bf-rich-list;
25
+ container-type: inline-size;
26
+ min-inline-size: 0;
27
+ padding-block-end: calc(var(--bf-section-space) / 2);
28
+ }
29
+
30
+ :where(.bf-theme) :where(.bf-rich-list.is-shallow) {
31
+ padding-block-end: var(--bf-section-space-shallow);
32
+ }
33
+
34
+ :where(.bf-theme) :where(.bf-rich-list.is-deep) {
35
+ padding-block-end: calc(var(--bf-section-space-deep) / 2);
36
+ }
37
+
38
+ :where(.bf-theme) :where(.bf-rich-list-layout) {
39
+ display: grid;
40
+ grid-template-columns: minmax(0, 1fr);
41
+ min-inline-size: 0;
42
+ }
43
+
44
+ :where(.bf-theme) :where(.bf-rich-list-rule) {
45
+ grid-column: 1 / -1;
46
+ order: -2;
47
+ }
48
+
49
+ :where(.bf-theme) :where(.bf-rich-list-header, .bf-rich-list-support, .bf-rich-list-content, .bf-rich-list-media, .bf-rich-list-list-slot, .bf-rich-list-cta) {
50
+ min-inline-size: 0;
51
+ overflow-wrap: anywhere;
52
+ }
53
+
54
+ @media (width >= 64.75rem) {
55
+ :where(.bf-theme) :where(.bf-rich-list:not(.is-shallow)) {
56
+ padding-block-end: var(--bf-section-space);
57
+ }
58
+
59
+ :where(.bf-theme) :where(.bf-rich-list.is-deep) {
60
+ padding-block-end: var(--bf-section-space-deep);
61
+ }
62
+ }
63
+
64
+ /* ------------------------------------------------------------------ */
65
+ /* Horizontal: the full composition remains stacked. The 50/50 variant */
66
+ /* places title and support in equal logical rails at the large split. */
67
+ /* ------------------------------------------------------------------ */
68
+
69
+ :where(.bf-theme) :where(.bf-rich-list.is-horizontal) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-visual, .bf-rich-list-header, .bf-rich-list-support, .bf-rich-list-list-slot, .bf-rich-list-cta-rule) {
70
+ grid-column: 1 / -1;
71
+ }
72
+
73
+ :where(.bf-theme) :where(.bf-rich-list-visual) {
74
+ min-inline-size: 0;
75
+ overflow: hidden;
76
+ }
77
+
78
+ :where(.bf-theme) :where(.bf-rich-list-visual > :where(img, picture, svg, video, canvas)) {
79
+ block-size: auto;
80
+ display: block;
81
+ inline-size: 100%;
82
+ max-inline-size: 100%;
83
+ }
84
+
85
+ /* A full-width ratio inside a fluid Sites rail otherwise leaves the next
86
+ heading on a fractional pixel. The visual alone absorbs the trailing
87
+ compensation; semantic children retain their own margins unchanged. */
88
+ @supports (block-size: calc-size(auto, round(up, size, 1px))) {
89
+ :where(.bf-theme) :where(.bf-rich-list-visual > .bf-aspect) {
90
+ block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
91
+ }
92
+ }
93
+
94
+ :where(.bf-theme) :where(.bf-rich-list-list-slot) {
95
+ container-name: bf-rich-horizontal-items;
96
+ container-type: inline-size;
97
+ }
98
+
99
+ :where(.bf-theme) :where(.bf-rich-list-list) {
100
+ display: grid;
101
+ grid-template-columns: minmax(0, 1fr);
102
+ list-style: none;
103
+ margin: 0;
104
+ min-inline-size: 0;
105
+ padding: 0;
106
+ }
107
+
108
+ /* Vanilla gives every horizontal-list row a continuous leading divider. */
109
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item {
110
+ margin: 0;
111
+ padding-block: var(--bf-space-1) var(--bf-space-2);
112
+ position: relative;
113
+ }
114
+
115
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after {
116
+ background: var(--bf-color-border-low-contrast);
117
+ block-size: var(--bf-border-width);
118
+ content: "";
119
+ inset-block-start: 0;
120
+ inset-inline-start: 0;
121
+ inline-size: 100%;
122
+ position: absolute;
123
+ }
124
+
125
+ /* Prefixes are logical here even though the shared list predates BF's
126
+ logical-property rule. This keeps ticks, bullets and numbers RTL-safe. */
127
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:is(.is-ticked, .is-crossed) {
128
+ padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
129
+ }
130
+
131
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:is(.is-ticked, .is-crossed)::before {
132
+ inset: auto;
133
+ inset-inline-start: 0;
134
+ inset-block-start: calc(var(--bf-body-nudge-start) + var(--bf-space-1));
135
+ }
136
+
137
+ :where(.bf-theme) :where(.bf-rich-list-list.is-bulleted) > :where(.bf-list-item) {
138
+ padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
139
+ }
140
+
141
+ :where(.bf-theme) :where(.bf-rich-list-list.is-bulleted) > :where(.bf-list-item)::before {
142
+ color: var(--bf-color-text-default);
143
+ content: "•";
144
+ inline-size: var(--bf-leading-icon-size);
145
+ inset-block-start: var(--bf-space-1);
146
+ inset-inline-start: 0;
147
+ position: absolute;
148
+ text-align: center;
149
+ }
150
+
151
+ :where(.bf-theme) :where(ol.bf-rich-list-list) {
152
+ counter-reset: bf-rich-horizontal-counter;
153
+ }
154
+
155
+ :where(.bf-theme) :where(ol.bf-rich-list-list) > :where(.bf-list-item) {
156
+ counter-increment: bf-rich-horizontal-counter;
157
+ padding-inline-start: calc(var(--bf-leading-icon-size) + var(--bf-leading-icon-gap));
158
+ }
159
+
160
+ :where(.bf-theme) :where(ol.bf-rich-list-list) > :where(.bf-list-item)::before {
161
+ color: var(--bf-color-text-default);
162
+ content: counter(bf-rich-horizontal-counter) ".";
163
+ inline-size: var(--bf-leading-icon-size);
164
+ inset-block-start: var(--bf-space-1);
165
+ inset-inline-start: 0;
166
+ position: absolute;
167
+ text-align: end;
168
+ }
169
+
170
+ /* Vanilla's list measures are content-derived: one column below 66ch, two
171
+ from 66ch, and four from 100ch. Pseudo-rules span the complete row. */
172
+ @container bf-rich-horizontal-items (width >= 66ch) {
173
+ :where(.bf-theme) :where(.bf-rich-list-list) {
174
+ column-gap: var(--bf-grid-gap-inline);
175
+ grid-template-columns: repeat(2, minmax(0, 1fr));
176
+ }
177
+
178
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after {
179
+ content: none;
180
+ }
181
+
182
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(2n + 1)::after {
183
+ content: "";
184
+ inline-size: calc(200% + var(--bf-grid-gap-inline));
185
+ }
186
+ }
187
+
188
+ @container bf-rich-horizontal-items (width >= 100ch) {
189
+ :where(.bf-theme) :where(.bf-rich-list-list) {
190
+ grid-template-columns: repeat(4, minmax(0, 1fr));
191
+ }
192
+
193
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item::after,
194
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(2n + 1)::after {
195
+ content: none;
196
+ }
197
+
198
+ :where(.bf-theme) :where(.bf-rich-list-list) > .bf-list-item:nth-child(4n + 1)::after {
199
+ content: "";
200
+ inline-size: calc(400% + (var(--bf-grid-gap-inline) * 3));
201
+ }
202
+ }
203
+
204
+ @container bf-rich-list (width >= 64.75rem) {
205
+ :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) {
206
+ column-gap: var(--bf-grid-gap-inline);
207
+ grid-template-columns: repeat(2, minmax(0, 1fr));
208
+ }
209
+
210
+ :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-header) {
211
+ grid-column: 1;
212
+ }
213
+
214
+ :where(.bf-theme) :where(.bf-rich-list.is-horizontal.is-50-50) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-support) {
215
+ grid-column: 2;
216
+ }
217
+
218
+ :where(.bf-theme) :where(.bf-rich-list.is-horizontal) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-cta) {
219
+ grid-column: 2;
220
+ }
221
+ }
222
+
223
+ /* ------------------------------------------------------------------ */
224
+ /* Vertical: a rich media object, not a Jinja content-block adapter. */
225
+ /* ------------------------------------------------------------------ */
226
+
227
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-rule) {
228
+ grid-column: 1 / -1;
229
+ }
230
+
231
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical) :where(.bf-rich-list-media) {
232
+ container-type: inline-size;
233
+ padding-block-end: var(--bf-section-space-shallow);
234
+ }
235
+
236
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) :where(.bf-rich-list-media) {
237
+ order: -1;
238
+ }
239
+
240
+ :where(.bf-theme) :where(.bf-rich-list-media-frame) {
241
+ aspect-ratio: 3 / 2;
242
+ display: block;
243
+ inline-size: 100%;
244
+ max-inline-size: 100%;
245
+ overflow: hidden;
246
+ position: relative;
247
+ }
248
+
249
+ /* The media object deliberately stretches across fluid 1/2 and 2/3 ratios.
250
+ Snap that resulting block, rather than resetting content spacing, so each
251
+ tier's baseline survives both portrait and landscape allocations. */
252
+ @supports (block-size: calc-size(auto, round(up, size, 1px))) {
253
+ :where(.bf-theme) :where(.bf-rich-list-media-frame) {
254
+ block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
255
+ }
256
+ }
257
+
258
+ :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-3-2) :where(.bf-rich-list-media-frame) {
259
+ aspect-ratio: 3 / 2;
260
+ }
261
+
262
+ :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-16-9) :where(.bf-rich-list-media-frame),
263
+ :where(.bf-theme) :where(.bf-rich-list-media.is-video) :where(.bf-rich-list-media-frame) {
264
+ aspect-ratio: 16 / 9;
265
+ }
266
+
267
+ :where(.bf-theme) :where(.bf-rich-list-media.is-narrow-square) :where(.bf-rich-list-media-frame) {
268
+ aspect-ratio: 1 / 1;
269
+ }
270
+
271
+ :where(.bf-theme) :where(.bf-rich-list-media > .bf-rich-list-media-frame > :where(img, picture, svg, video, canvas, iframe)) {
272
+ block-size: 100%;
273
+ border: 0;
274
+ display: block;
275
+ inline-size: 100%;
276
+ max-inline-size: 100%;
277
+ object-fit: cover;
278
+ }
279
+
280
+ :where(.bf-theme) :where(.bf-rich-list-media > .bf-rich-list-media-frame > :where(picture) > :where(img)) {
281
+ block-size: 100%;
282
+ display: block;
283
+ inline-size: 100%;
284
+ object-fit: cover;
285
+ }
286
+
287
+ :where(.bf-theme) :where(.bf-rich-list-media.is-contain > .bf-rich-list-media-frame > :where(img, svg, video, canvas)),
288
+ :where(.bf-theme) :where(.bf-rich-list-media.is-contain > .bf-rich-list-media-frame > :where(picture) > :where(img)) {
289
+ object-fit: contain;
290
+ }
291
+
292
+ /* Auto height has no shallow media wrapper in Vanilla. At narrow widths it
293
+ remains a normal 3:2 frame; at the wide split it stretches with the content
294
+ rail, clamped between the equivalent 16:9 and 2:3 heights. */
295
+ :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) {
296
+ padding-block-end: 0;
297
+ }
298
+
299
+ @container bf-rich-list (width >= 64.75rem) {
300
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) {
301
+ align-items: stretch;
302
+ column-gap: var(--bf-grid-gap-inline);
303
+ grid-template-columns: repeat(2, minmax(0, 1fr));
304
+ }
305
+
306
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-content) {
307
+ grid-column: 1;
308
+ grid-row: 2;
309
+ }
310
+
311
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-media) {
312
+ grid-column: 2;
313
+ grid-row: 2;
314
+ order: 0;
315
+ }
316
+
317
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-content) {
318
+ grid-column: 2;
319
+ }
320
+
321
+ :where(.bf-theme) :where(.bf-rich-list.is-vertical.is-flipped) > :where(.bf-rich-list-layout) > :where(.bf-rich-list-media) {
322
+ grid-column: 1;
323
+ }
324
+
325
+ :where(.bf-theme) :where(.bf-rich-list-media.is-wide-16-9) :where(.bf-rich-list-media-frame) {
326
+ aspect-ratio: 16 / 9;
327
+ }
328
+
329
+ :where(.bf-theme) :where(.bf-rich-list-media.is-wide-3-2) :where(.bf-rich-list-media-frame) {
330
+ aspect-ratio: 3 / 2;
331
+ }
332
+
333
+ :where(.bf-theme) :where(.bf-rich-list-media.is-wide-square) :where(.bf-rich-list-media-frame) {
334
+ aspect-ratio: 1 / 1;
335
+ }
336
+
337
+ :where(.bf-theme) :where(.bf-rich-list-media.is-wide-2-3) :where(.bf-rich-list-media-frame) {
338
+ aspect-ratio: 2 / 3;
339
+ }
340
+
341
+ :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) :where(.bf-rich-list-media-frame) {
342
+ aspect-ratio: auto;
343
+ block-size: 100%;
344
+ max-block-size: 150cqi;
345
+ min-block-size: 56.25cqi;
346
+ }
347
+
348
+ @supports (min-block-size: round(up, 1px, 1px)) {
349
+ :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height) :where(.bf-rich-list-media-frame) {
350
+ max-block-size: round(down, 150cqi, var(--bf-baseline));
351
+ min-block-size: round(up, 56.25cqi, var(--bf-baseline));
352
+ }
353
+ }
354
+
355
+ /* Vanilla's auto-height image is absolutely positioned inside the clamped
356
+ frame. Removing intrinsic media from track sizing lets the content rail
357
+ determine the shared row before the 16:9/2:3 clamps are applied. */
358
+ :where(.bf-theme) :where(.bf-rich-list-media.is-auto-height > .bf-rich-list-media-frame > :where(img, picture, svg, video, canvas, iframe)) {
359
+ inset: 0;
360
+ position: absolute;
361
+ }
362
+ }
363
363
  `;
364
364
  }