baseline-foundry 0.1.3 → 0.1.5

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