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
@@ -3,14 +3,14 @@
3
3
  * separate family from the general-purpose `bf-card` primitive.
4
4
  *
5
5
  * Vanilla -> BF rhythm mapping (Vanilla's spacing unit is 0.5rem):
6
- * - 16px content padding/gap -> `--bf-space-2`.
7
- * - 8px footer/image spacing -> `--bf-space-1`.
8
- * - 32px wrapper separation -> `--bf-space-4`.
9
- * - 380px vertical minimum -> 48 BF baselines (384px in editorial), avoiding
6
+ * - 1rem content padding/gap -> `--bf-space-2`.
7
+ * - 0.5rem footer/image spacing -> `--bf-space-1`.
8
+ * - 2rem wrapper separation -> `--bf-space-4`.
9
+ * - 23.75rem vertical minimum -> 48 BF baselines (24rem in editorial), avoiding
10
10
  * Vanilla's half-baseline ending while retaining its occupied silhouette.
11
- * - 192px horizontal/text minimum -> 24 BF baselines.
12
- * - 352px eight-column minimum -> 44 BF baselines.
13
- * - 284px horizontal media width -> 36 BF baselines (288px in editorial).
11
+ * - 12rem horizontal/text minimum -> 24 BF baselines.
12
+ * - 22rem eight-column minimum -> 44 BF baselines.
13
+ * - 17.75rem horizontal media width -> 36 BF baselines (18rem in editorial).
14
14
  *
15
15
  * The root card establishes a named query container. Only descendants change
16
16
  * inside container queries; this avoids the invalid query-the-container-itself
@@ -23,495 +23,496 @@
23
23
  * reachable.
24
24
  */
25
25
  export function contentCardCss() {
26
- return `/* ------------------------------------------------------------------ */
27
- /* Content card — rich Vanilla parity, distinct from the bf-card primitive. */
28
- /* ------------------------------------------------------------------ */
29
-
30
- :where(.bf-theme) :where(.bf-content-card-wrapper) {
31
- block-size: auto;
32
- display: flex;
33
- flex-direction: column;
34
- grid-column: 1 / -1;
35
- inline-size: 100%;
36
- min-inline-size: 0;
37
- padding-block-end: var(--bf-space-4);
38
- }
39
-
40
- /* Snap the grid-row wrapper after intrinsic image/copy measurement. Because
41
- the card flexes inside it, peers retain Vanilla's equal-height row while
42
- the card edge and the following row both land on BF baselines. */
43
- @supports (block-size: calc-size(auto, round(up, size, 1px))) {
44
- :where(.bf-theme) :where(.bf-content-card-wrapper) {
45
- block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
46
- }
47
- }
48
-
49
- /* Vanilla's column names describe its eight-column grid. BF doubles the span
50
- when its own large-screen grid becomes sixteen columns. */
51
- @media (width >= 38.75rem) {
52
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-2) {
53
- grid-column: auto / span 2;
54
- }
55
- }
56
-
57
- @media (width >= 64.75rem) {
58
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-4) {
59
- grid-column: auto / span 4;
60
- }
61
-
62
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-6) {
63
- grid-column: auto / span 6;
64
- }
65
- }
66
-
67
- @media (width >= 105.0625rem) {
68
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-2) {
69
- grid-column: auto / span 4;
70
- }
71
-
72
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-4) {
73
- grid-column: auto / span 8;
74
- }
75
-
76
- :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-6) {
77
- grid-column: auto / span 12;
78
- }
79
- }
80
-
81
- :where(.bf-theme) :where(.bf-content-card) {
82
- background: var(--bf-color-background-default);
83
- border: var(--bf-border-width) solid var(--bf-color-border-low-contrast);
84
- box-sizing: border-box;
85
- color: var(--bf-color-text-default);
86
- container-name: bf-content-card;
87
- container-type: inline-size;
88
- flex: 1;
89
- inline-size: 100%;
90
- max-inline-size: 100%;
91
- min-inline-size: 0;
92
- overflow: hidden;
93
- position: relative;
94
- transition: border-color 400ms ease-in-out;
95
- }
96
-
97
- :where(.bf-theme) :where(.bf-content-card:hover, .bf-content-card:focus-within) {
98
- border-color: var(--bf-color-border-high-contrast);
99
- }
100
-
101
- :where(.bf-theme) :where(.bf-content-card-frame) {
102
- align-items: stretch;
103
- display: flex;
104
- flex-direction: column;
105
- inline-size: 100%;
106
- min-block-size: calc(var(--bf-space-12) - (var(--bf-border-width) * 2));
107
- min-inline-size: 0;
108
- padding-block-start: var(--bf-space-2);
109
- }
110
-
111
- :where(.bf-theme) :where(.bf-content-card.is-image) :where(.bf-content-card-frame) {
112
- min-block-size: calc((var(--bf-space-12) * 4) - (var(--bf-border-width) * 2));
113
- padding-block-start: 0;
114
- }
115
-
116
- :where(.bf-theme) :where(.bf-content-card:not(.is-image)) :where(.bf-content-card-frame) {
117
- min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
118
- }
119
-
120
- :where(.bf-theme) :where(.bf-content-card-media) {
121
- align-items: flex-start;
122
- display: flex;
123
- flex: 0 0 auto;
124
- flex-direction: column;
125
- inline-size: 100%;
126
- max-inline-size: 100%;
127
- min-inline-size: 0;
128
- padding-block-end: var(--bf-space-2);
129
- }
130
-
131
- :where(.bf-theme) :where(.bf-content-card-image) {
132
- aspect-ratio: 16 / 9;
133
- block-size: auto;
134
- /* Preserve 16:9 within half a baseline while keeping the occupied media
135
- block on BF's grid at arbitrary card widths. */
136
- block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
137
- display: block;
138
- flex: 0 0 auto;
139
- inline-size: 100%;
140
- margin: 0;
141
- max-inline-size: 100%;
142
- object-fit: cover;
143
- }
144
-
145
- :where(.bf-theme) :where(.bf-content-card-content) {
146
- display: flex;
147
- flex: 1;
148
- flex-direction: column;
149
- inline-size: 100%;
150
- justify-content: space-between;
151
- min-block-size: 0;
152
- min-inline-size: 0;
153
- }
154
-
155
- :where(.bf-theme) :where(.bf-content-card-body) {
156
- align-items: flex-start;
157
- align-self: stretch;
158
- display: grid;
159
- grid-template-columns: minmax(0, 1fr);
160
- grid-template-rows: minmax(0, 1fr);
161
- min-inline-size: 0;
162
- overflow: hidden;
163
- padding-inline: var(--bf-space-2);
164
- }
165
-
166
- :where(.bf-theme) :where(.bf-content-card-primary, .bf-content-card-description-panel) {
167
- display: flex;
168
- flex-direction: column;
169
- grid-area: 1 / 1;
170
- inline-size: 100%;
171
- min-inline-size: 0;
172
- }
173
-
174
- :where(.bf-theme) :where(.bf-content-card-primary) {
175
- opacity: 1;
176
- transition: opacity 400ms ease-in-out;
177
- }
178
-
179
- :where(.bf-theme) :where(.bf-content-card-description-panel) {
180
- opacity: 0;
181
- transform: translateY(calc(var(--bf-space-12) + var(--bf-space-6)));
182
- transition: opacity 400ms ease-in-out, transform 400ms ease-in-out;
183
- }
184
-
185
- /* A content-card title is a real heading slot. It uses BF's h4 role in the
186
- 2/4/6-column variants and the h1 role in the eight-column feature. */
187
- :where(.bf-theme) :where(.bf-content-card-title) {
188
- color: var(--bf-color-text-default);
189
- font-family: var(--bf-h4-font-family);
190
- font-size: var(--bf-h4-font-size);
191
- font-style: var(--bf-h4-font-style);
192
- font-variant-caps: var(--bf-h4-font-variant-caps);
193
- font-weight: var(--bf-h4-font-weight);
194
- inline-size: 100%;
195
- letter-spacing: var(--bf-h4-letter-spacing);
196
- line-height: var(--bf-h4-line-height);
197
- margin-block: 0 var(--bf-h4-margin-bottom);
198
- max-inline-size: none;
199
- min-inline-size: 0;
200
- overflow-wrap: anywhere;
201
- padding-block-end: 0;
202
- padding-block-start: var(--bf-h4-nudge-start);
203
- text-transform: var(--bf-h4-text-transform);
204
- }
205
-
206
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-title) {
207
- font-family: var(--bf-h1-font-family);
208
- font-size: var(--bf-h1-font-size);
209
- font-style: var(--bf-h1-font-style);
210
- font-variant-caps: var(--bf-h1-font-variant-caps);
211
- font-weight: var(--bf-h1-font-weight);
212
- letter-spacing: var(--bf-h1-letter-spacing);
213
- line-height: var(--bf-h1-line-height);
214
- margin-block-end: var(--bf-h1-margin-bottom);
215
- padding-block-end: 0;
216
- padding-block-start: var(--bf-h1-nudge-start);
217
- text-transform: var(--bf-h1-text-transform);
218
- }
219
-
220
- :where(.bf-theme) :where(.bf-content-card-main-link) {
221
- -webkit-box-orient: vertical;
222
- -webkit-line-clamp: 3;
223
- color: inherit;
224
- cursor: pointer;
225
- display: -webkit-box;
226
- inline-size: 100%;
227
- line-clamp: 3;
228
- min-inline-size: 0;
229
- overflow: hidden;
230
- text-decoration: none;
231
- }
232
-
233
- :where(.bf-theme) :where(.bf-content-card-main-link)::after {
234
- content: "";
235
- inset: 0;
236
- position: absolute;
237
- z-index: 1;
238
- }
239
-
240
- :where(.bf-theme) :where(.bf-content-card-main-link:is(:hover, :focus, :active, :visited)) {
241
- color: inherit;
242
- text-decoration: none;
243
- }
244
-
245
- :where(.bf-theme) :where(.bf-content-card-main-link:focus) {
246
- outline: none;
247
- }
248
-
249
- :where(.bf-theme) :where(.bf-content-card:has(.bf-content-card-main-link:focus-visible)) {
250
- outline: 3px solid var(--bf-color-focus);
251
- outline-offset: 2px;
252
- }
253
-
254
- /* All nested actions sit above the expanded main-link hit area. This includes
255
- consumer-supplied controls as well as the documented author-link slot. */
256
- :where(.bf-theme) :where(.bf-content-card) :where(a, button, input, select, textarea, summary):not(.bf-content-card-main-link),
257
- :where(.bf-theme) :where(.bf-content-card-interactive) {
258
- pointer-events: auto;
259
- position: relative;
260
- z-index: 2;
261
- }
262
-
263
- :where(.bf-theme) :where(.bf-content-card-author-date) {
264
- align-items: flex-start;
265
- color: var(--bf-color-text-muted);
266
- display: flex;
267
- flex-wrap: wrap;
268
- gap: 0 var(--bf-space-half);
269
- min-inline-size: 0;
270
- padding-block-end: var(--bf-space-1);
271
- }
272
-
273
- :where(.bf-theme) :where(.bf-content-card-author-date > *) {
274
- margin-block-end: 0;
275
- }
276
-
277
- :where(.bf-theme) :where(.bf-content-card-description) {
278
- -webkit-box-orient: vertical;
279
- -webkit-line-clamp: 4;
280
- display: -webkit-box;
281
- line-clamp: 4;
282
- max-inline-size: none;
283
- min-inline-size: 0;
284
- overflow: hidden;
285
- overflow-wrap: anywhere;
286
- }
287
-
288
- :where(.bf-theme) :where(.bf-content-card.is-cols-6) :where(.bf-content-card-main-link, .bf-content-card-description) {
289
- -webkit-line-clamp: 2;
290
- line-clamp: 2;
291
- }
292
-
293
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-body) {
294
- display: flex;
295
- flex-direction: column;
296
- min-block-size: 0;
297
- }
298
-
299
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description-panel) {
300
- flex: 1;
301
- opacity: 1;
302
- transform: translateY(0);
303
- }
304
-
305
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description) {
306
- -webkit-line-clamp: 2;
307
- line-clamp: 2;
308
- margin-block-end: var(--bf-space-2);
309
- }
310
-
311
- :where(.bf-theme) :where(.bf-content-card-footer) {
312
- border-block-start: var(--bf-border-width) solid var(--bf-color-border-low-contrast);
313
- inline-size: 100%;
314
- min-inline-size: 0;
315
- }
316
-
317
- :where(.bf-theme) :where(.bf-content-card-footer-inner) {
318
- align-items: center;
319
- display: flex;
320
- gap: var(--bf-space-1);
321
- inline-size: 100%;
322
- mask-image: linear-gradient(to right, #000 85%, transparent 100%);
323
- min-block-size: var(--bf-space-4);
324
- min-inline-size: 0;
325
- overflow-x: auto;
326
- padding-block-end: var(--bf-space-1);
327
- padding-inline: var(--bf-space-2);
328
- position: relative;
329
- scrollbar-width: none;
330
- z-index: 2;
331
- }
332
-
333
- :where([dir='rtl'].bf-theme, [dir='rtl'] .bf-theme) :where(.bf-content-card-footer-inner),
334
- :where(.bf-theme) :where([dir='rtl'] .bf-content-card-footer-inner) {
335
- mask-image: linear-gradient(to left, #000 85%, transparent 100%);
336
- }
337
-
338
- :where(.bf-theme) :where(.bf-content-card-footer-inner::-webkit-scrollbar) {
339
- display: none;
340
- }
341
-
342
- :where(.bf-theme) :where(.bf-content-card-footer-inner > *) {
343
- flex: 0 0 auto;
344
- white-space: nowrap;
345
- }
346
-
347
- :where(.bf-theme) :where(.bf-content-card-resource) {
348
- align-items: center;
349
- display: inline-flex;
350
- gap: var(--bf-space-half);
351
- }
352
-
353
- :where(.bf-theme) :where(.bf-content-card-resource > *) {
354
- margin: 0;
355
- }
356
-
357
- :where(.bf-theme) :where(.bf-content-card-footer .bf-chip) {
358
- margin: 0;
359
- margin-inline-end: var(--bf-space-3);
360
- }
361
-
362
- /* Internal geometry responds to the card's allocated width. The card root is
363
- only the container; the frame/media/body descendants own queried styles. */
364
- /* Vanilla switches the viewport at 620px/1036px. A four-column card is much
365
- narrower than that viewport after grid margins and gutters, so its internal
366
- horizontal layout uses Vanilla's 460px minimum viable allocation. The
367
- eight-column 50/50 split starts at the roughly 960px allocation left by the
368
- 1036px viewport. This preserves the rendered switch in embedded BF grids. */
369
- @container bf-content-card (width < 28.75rem) {
370
- :where(.bf-theme) :where(.bf-content-card-frame:not(:has(.bf-content-card-footer))) {
371
- min-block-size: 0;
372
- padding-block-end: calc(var(--bf-space-2) - (var(--bf-border-width) * 2));
373
- }
374
- }
375
-
376
- @container bf-content-card (width >= 28.75rem) {
377
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-frame) {
378
- column-gap: var(--bf-space-2);
379
- flex-direction: row;
380
- min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
381
- padding: var(--bf-space-2) var(--bf-space-2) 0;
382
- }
383
-
384
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6):not(.is-image)) :where(.bf-content-card-frame) {
385
- min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
386
- }
387
-
388
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-media) {
389
- align-self: stretch;
390
- inline-size: calc(var(--bf-space-12) * 3);
391
- padding-block-end: 0;
392
- }
393
-
394
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-image) {
395
- aspect-ratio: 16 / 9;
396
- block-size: auto;
397
- block-size: calc(var(--bf-space-12) + var(--bf-space-8));
398
- }
399
-
400
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-body) {
401
- padding-inline: 0;
402
- }
403
-
404
- :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-footer-inner) {
405
- padding-inline: 0;
406
- }
407
-
408
- /* An explicit image-top modifier wins after the horizontal rules. */
409
- :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-frame) {
410
- flex-direction: column;
411
- min-block-size: calc((var(--bf-space-12) * 4) - (var(--bf-border-width) * 2));
412
- padding: 0;
413
- }
414
-
415
- :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-media) {
416
- inline-size: 100%;
417
- padding-block-end: var(--bf-space-2);
418
- }
419
-
420
- :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-image) {
421
- aspect-ratio: 16 / 9;
422
- block-size: auto;
423
- block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
424
- }
425
-
426
- :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-body, .bf-content-card-footer-inner) {
427
- padding-inline: var(--bf-space-2);
428
- }
429
- }
430
-
431
- @container bf-content-card (width >= 60rem) {
432
- :where(.bf-theme) :where(.bf-content-card.is-cols-8.is-image) :where(.bf-content-card-frame) {
433
- display: grid;
434
- grid-template-columns: repeat(2, minmax(0, 1fr));
435
- min-block-size: calc((var(--bf-space-12) * 3 + var(--bf-space-8)) - (var(--bf-border-width) * 2));
436
- padding: 0;
437
- }
438
-
439
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-content) {
440
- grid-column: 1;
441
- grid-row: 1;
442
- }
443
-
444
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-body) {
445
- padding-block-start: var(--bf-space-2);
446
- }
447
-
448
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-media) {
449
- block-size: 100%;
450
- grid-column: 2;
451
- grid-row: 1;
452
- padding: var(--bf-space-1) var(--bf-space-1) 0;
453
- }
454
-
455
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-image) {
456
- aspect-ratio: auto;
457
- block-size: 100%;
458
- }
459
-
460
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description) {
461
- -webkit-line-clamp: 3;
462
- line-clamp: 3;
463
- margin-block-end: 0;
464
- }
465
-
466
- :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8.is-image) :where(.bf-content-card-frame) {
467
- display: flex;
468
- flex-direction: column;
469
- }
470
-
471
- :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8) :where(.bf-content-card-media) {
472
- block-size: auto;
473
- padding: 0 0 var(--bf-space-2);
474
- }
475
-
476
- :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8) :where(.bf-content-card-image) {
477
- aspect-ratio: 16 / 9;
478
- block-size: auto;
479
- block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
480
- }
481
- }
482
-
483
- @media (38.75rem <= width < 64.75rem) {
484
- :where(.bf-theme) :where(.bf-content-card.is-cols-2) :where(.bf-content-card-author-date),
485
- :where(.bf-theme) :where(.bf-content-card.is-cols-6) :where(.bf-content-card-author-date) {
486
- display: none;
487
- }
488
-
489
- :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-main-link) {
490
- -webkit-line-clamp: 2;
491
- line-clamp: 2;
492
- }
493
- }
494
-
495
- /* Vanilla swaps primary copy for the optional description on desktop. Only
496
- hover or focus of the main action triggers the swap; focusing a nested
497
- author/footer action never makes that focused control disappear. */
498
- @media (width >= 64.75rem) {
499
- :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):hover) :where(.bf-content-card-primary),
500
- :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):has(.bf-content-card-main-link:focus-visible)) :where(.bf-content-card-primary) {
501
- opacity: 0;
502
- }
503
-
504
- :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):hover) :where(.bf-content-card-description-panel),
505
- :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):has(.bf-content-card-main-link:focus-visible)) :where(.bf-content-card-description-panel) {
506
- opacity: 1;
507
- transform: translateY(0);
508
- }
509
- }
510
-
511
- @media (prefers-reduced-motion: reduce) {
512
- :where(.bf-theme) :where(.bf-content-card, .bf-content-card-primary, .bf-content-card-description-panel) {
513
- transition-duration: 0.01ms;
514
- }
515
- }
26
+ return `/* ------------------------------------------------------------------ */
27
+ /* Content card — rich Vanilla parity, distinct from the bf-card primitive. */
28
+ /* ------------------------------------------------------------------ */
29
+
30
+ :where(.bf-theme) :where(.bf-content-card-wrapper) {
31
+ block-size: auto;
32
+ display: flex;
33
+ flex-direction: column;
34
+ grid-column: 1 / -1;
35
+ inline-size: 100%;
36
+ min-inline-size: 0;
37
+ padding-block-end: var(--bf-space-4);
38
+ }
39
+
40
+ /* Snap the grid-row wrapper after intrinsic image/copy measurement. Because
41
+ the card flexes inside it, peers retain Vanilla's equal-height row while
42
+ the card edge and the following row both land on BF baselines. */
43
+ @supports (block-size: calc-size(auto, round(up, size, 0.0625rem))) {
44
+ :where(.bf-theme) :where(.bf-content-card-wrapper) {
45
+ block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
46
+ }
47
+ }
48
+
49
+ /* Vanilla's column names describe its eight-column grid. BF doubles the span
50
+ when its own large-screen grid becomes sixteen columns. */
51
+ @media (width >= 38.75rem) {
52
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-2) {
53
+ grid-column: auto / span 2;
54
+ }
55
+ }
56
+
57
+ @media (width >= 64.75rem) {
58
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-4) {
59
+ grid-column: auto / span 4;
60
+ }
61
+
62
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-6) {
63
+ grid-column: auto / span 6;
64
+ }
65
+ }
66
+
67
+ @media (width >= 105.0625rem) {
68
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-2) {
69
+ grid-column: auto / span 4;
70
+ }
71
+
72
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-4) {
73
+ grid-column: auto / span 8;
74
+ }
75
+
76
+ :where(.bf-theme) :where(.bf-content-card-wrapper.is-cols-6) {
77
+ grid-column: auto / span 12;
78
+ }
79
+ }
80
+
81
+ :where(.bf-theme) :where(.bf-content-card) {
82
+ background: var(--bf-color-background-default);
83
+ border: var(--bf-border-width) solid var(--bf-color-border-low-contrast);
84
+ box-sizing: border-box;
85
+ color: var(--bf-color-text-default);
86
+ container-name: bf-content-card;
87
+ container-type: inline-size;
88
+ flex: 1;
89
+ inline-size: 100%;
90
+ max-inline-size: 100%;
91
+ min-inline-size: 0;
92
+ overflow: hidden;
93
+ position: relative;
94
+ transition: border-color 400ms ease-in-out;
95
+ }
96
+
97
+ :where(.bf-theme) :where(.bf-content-card:hover, .bf-content-card:focus-within) {
98
+ border-color: var(--bf-color-border-high-contrast);
99
+ }
100
+
101
+ :where(.bf-theme) :where(.bf-content-card-frame) {
102
+ align-items: stretch;
103
+ display: flex;
104
+ flex-direction: column;
105
+ inline-size: 100%;
106
+ min-block-size: calc(var(--bf-space-12) - (var(--bf-border-width) * 2));
107
+ min-inline-size: 0;
108
+ padding-block-start: var(--bf-space-2);
109
+ }
110
+
111
+ :where(.bf-theme) :where(.bf-content-card.is-image) :where(.bf-content-card-frame) {
112
+ min-block-size: calc((var(--bf-space-12) * 4) - (var(--bf-border-width) * 2));
113
+ padding-block-start: 0;
114
+ }
115
+
116
+ :where(.bf-theme) :where(.bf-content-card:not(.is-image)) :where(.bf-content-card-frame) {
117
+ min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
118
+ }
119
+
120
+ :where(.bf-theme) :where(.bf-content-card-media) {
121
+ align-items: flex-start;
122
+ display: flex;
123
+ flex: 0 0 auto;
124
+ flex-direction: column;
125
+ inline-size: 100%;
126
+ max-inline-size: 100%;
127
+ min-inline-size: 0;
128
+ padding-block-end: var(--bf-space-2);
129
+ }
130
+
131
+ :where(.bf-theme) :where(.bf-content-card-image) {
132
+ aspect-ratio: 16 / 9;
133
+ block-size: auto;
134
+ /* Preserve 16:9 within half a baseline while keeping the occupied media
135
+ block on BF's grid at arbitrary card widths. */
136
+ block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
137
+ display: block;
138
+ flex: 0 0 auto;
139
+ inline-size: 100%;
140
+ margin: 0;
141
+ max-inline-size: 100%;
142
+ object-fit: cover;
143
+ }
144
+
145
+ :where(.bf-theme) :where(.bf-content-card-content) {
146
+ display: flex;
147
+ flex: 1;
148
+ flex-direction: column;
149
+ inline-size: 100%;
150
+ justify-content: space-between;
151
+ min-block-size: 0;
152
+ min-inline-size: 0;
153
+ }
154
+
155
+ :where(.bf-theme) :where(.bf-content-card-body) {
156
+ align-items: flex-start;
157
+ align-self: stretch;
158
+ display: grid;
159
+ grid-template-columns: minmax(0, 1fr);
160
+ grid-template-rows: minmax(0, 1fr);
161
+ min-inline-size: 0;
162
+ overflow: hidden;
163
+ padding-inline: var(--bf-space-2);
164
+ }
165
+
166
+ :where(.bf-theme) :where(.bf-content-card-primary, .bf-content-card-description-panel) {
167
+ display: flex;
168
+ flex-direction: column;
169
+ grid-area: 1 / 1;
170
+ inline-size: 100%;
171
+ min-inline-size: 0;
172
+ }
173
+
174
+ :where(.bf-theme) :where(.bf-content-card-primary) {
175
+ opacity: 1;
176
+ transition: opacity 400ms ease-in-out;
177
+ }
178
+
179
+ :where(.bf-theme) :where(.bf-content-card-description-panel) {
180
+ opacity: 0;
181
+ transform: translateY(calc(var(--bf-space-12) + var(--bf-space-6)));
182
+ transition: opacity 400ms ease-in-out, transform 400ms ease-in-out;
183
+ }
184
+
185
+ /* A content-card title is a real heading slot. It uses BF's h4 role in the
186
+ 2/4/6-column variants and the h1 role in the eight-column feature. */
187
+ :where(.bf-theme) :where(.bf-content-card-title) {
188
+ color: var(--bf-color-text-default);
189
+ font-family: var(--bf-h4-font-family);
190
+ font-size: var(--bf-h4-font-size);
191
+ font-style: var(--bf-h4-font-style);
192
+ font-variant-caps: var(--bf-h4-font-variant-caps);
193
+ font-weight: var(--bf-h4-font-weight);
194
+ inline-size: 100%;
195
+ letter-spacing: var(--bf-h4-letter-spacing);
196
+ line-height: var(--bf-h4-line-height);
197
+ margin-block: 0 var(--bf-h4-margin-bottom);
198
+ max-inline-size: none;
199
+ min-inline-size: 0;
200
+ overflow-wrap: anywhere;
201
+ padding-block-end: 0;
202
+ padding-block-start: var(--bf-h4-nudge-start);
203
+ text-transform: var(--bf-h4-text-transform);
204
+ }
205
+
206
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-title) {
207
+ font-family: var(--bf-h1-font-family);
208
+ font-size: var(--bf-h1-font-size);
209
+ font-style: var(--bf-h1-font-style);
210
+ font-variant-caps: var(--bf-h1-font-variant-caps);
211
+ font-weight: var(--bf-h1-font-weight);
212
+ letter-spacing: var(--bf-h1-letter-spacing);
213
+ line-height: var(--bf-h1-line-height);
214
+ margin-block-end: var(--bf-h1-margin-bottom);
215
+ padding-block-end: 0;
216
+ padding-block-start: var(--bf-h1-nudge-start);
217
+ text-transform: var(--bf-h1-text-transform);
218
+ }
219
+
220
+ :where(.bf-theme) :where(a.bf-content-card-main-link) {
221
+ -webkit-box-orient: vertical;
222
+ -webkit-line-clamp: 3;
223
+ color: inherit;
224
+ cursor: pointer;
225
+ display: -webkit-box;
226
+ inline-size: 100%;
227
+ line-clamp: 3;
228
+ min-inline-size: 0;
229
+ overflow: hidden;
230
+ text-decoration: none;
231
+ }
232
+
233
+ :where(.bf-theme) :where(.bf-content-card-main-link)::after {
234
+ content: "";
235
+ inset: 0;
236
+ position: absolute;
237
+ z-index: 1;
238
+ }
239
+
240
+ :where(.bf-theme) :where(a.bf-content-card-main-link:is(:hover, :focus, :active, :visited)) {
241
+ color: inherit;
242
+ text-decoration: none;
243
+ }
244
+
245
+ :where(.bf-theme) :where(.bf-content-card-main-link:focus) {
246
+ outline: none;
247
+ }
248
+
249
+ :where(.bf-theme) :where(.bf-content-card:has(.bf-content-card-main-link:focus-visible)) {
250
+ outline: 0.1875rem solid var(--bf-color-focus);
251
+ outline-offset: 0.125rem;
252
+ }
253
+
254
+ /* All nested actions sit above the expanded main-link hit area. This includes
255
+ consumer-supplied controls as well as the documented author-link slot. */
256
+ :where(.bf-theme) :where(.bf-content-card) :where(a, button, input, select, textarea, summary):not(.bf-content-card-main-link),
257
+ :where(.bf-theme) :where(.bf-content-card-interactive) {
258
+ pointer-events: auto;
259
+ position: relative;
260
+ z-index: 2;
261
+ }
262
+
263
+ :where(.bf-theme) :where(.bf-content-card-author-date) {
264
+ align-items: flex-start;
265
+ color: var(--bf-color-text-muted);
266
+ display: flex;
267
+ flex-wrap: wrap;
268
+ gap: 0 var(--bf-space-half);
269
+ min-inline-size: 0;
270
+ padding-block-end: var(--bf-space-1);
271
+ }
272
+
273
+ :where(.bf-theme) :where(.bf-content-card-author-date > *) {
274
+ margin-block-end: 0;
275
+ }
276
+
277
+ :where(.bf-theme) :where(.bf-content-card-description) {
278
+ -webkit-box-orient: vertical;
279
+ -webkit-line-clamp: 4;
280
+ display: -webkit-box;
281
+ line-clamp: 4;
282
+ max-inline-size: none;
283
+ min-inline-size: 0;
284
+ overflow: hidden;
285
+ overflow-wrap: anywhere;
286
+ }
287
+
288
+ :where(.bf-theme) :where(.bf-content-card.is-cols-6) :where(.bf-content-card-main-link, .bf-content-card-description) {
289
+ -webkit-line-clamp: 2;
290
+ line-clamp: 2;
291
+ }
292
+
293
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-body) {
294
+ display: flex;
295
+ flex-direction: column;
296
+ min-block-size: 0;
297
+ }
298
+
299
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description-panel) {
300
+ flex: 1;
301
+ opacity: 1;
302
+ transform: translateY(0);
303
+ }
304
+
305
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description) {
306
+ -webkit-line-clamp: 2;
307
+ line-clamp: 2;
308
+ margin-block-end: var(--bf-space-2);
309
+ }
310
+
311
+ :where(.bf-theme) :where(.bf-content-card-footer) {
312
+ border-block-start: var(--bf-border-width) solid var(--bf-color-border-low-contrast);
313
+ inline-size: 100%;
314
+ min-inline-size: 0;
315
+ }
316
+
317
+ :where(.bf-theme) :where(.bf-content-card-footer-inner) {
318
+ align-items: center;
319
+ display: flex;
320
+ gap: var(--bf-space-1);
321
+ inline-size: 100%;
322
+ mask-image: linear-gradient(to right, #000 85%, transparent 100%);
323
+ min-block-size: var(--bf-space-4);
324
+ min-inline-size: 0;
325
+ overflow-x: auto;
326
+ padding-block-end: var(--bf-space-1);
327
+ padding-block-start: calc(0.5rem - var(--bf-border-width));
328
+ padding-inline: var(--bf-space-2);
329
+ position: relative;
330
+ scrollbar-width: none;
331
+ z-index: 2;
332
+ }
333
+
334
+ :where([dir='rtl'].bf-theme, [dir='rtl'] .bf-theme) :where(.bf-content-card-footer-inner),
335
+ :where(.bf-theme) :where([dir='rtl'] .bf-content-card-footer-inner) {
336
+ mask-image: linear-gradient(to left, #000 85%, transparent 100%);
337
+ }
338
+
339
+ :where(.bf-theme) :where(.bf-content-card-footer-inner::-webkit-scrollbar) {
340
+ display: none;
341
+ }
342
+
343
+ :where(.bf-theme) :where(.bf-content-card-footer-inner > *) {
344
+ flex: 0 0 auto;
345
+ white-space: nowrap;
346
+ }
347
+
348
+ :where(.bf-theme) :where(.bf-content-card-resource) {
349
+ align-items: center;
350
+ display: inline-flex;
351
+ gap: var(--bf-space-half);
352
+ }
353
+
354
+ :where(.bf-theme) :where(.bf-content-card-resource > *) {
355
+ margin: 0;
356
+ }
357
+
358
+ :where(.bf-theme) :where(.bf-content-card-footer .bf-chip) {
359
+ margin: 0;
360
+ margin-inline-end: var(--bf-space-3);
361
+ }
362
+
363
+ /* Internal geometry responds to the card's allocated width. The card root is
364
+ only the container; the frame/media/body descendants own queried styles. */
365
+ /* Vanilla switches the viewport at 38.75rem/64.75rem. A four-column card is much
366
+ narrower than that viewport after grid margins and gutters, so its internal
367
+ horizontal layout uses Vanilla's 28.75rem minimum viable allocation. The
368
+ eight-column 50/50 split starts at the roughly 60rem allocation left by the
369
+ 64.75rem viewport. This preserves the rendered switch in embedded BF grids. */
370
+ @container bf-content-card (width < 28.75rem) {
371
+ :where(.bf-theme) :where(.bf-content-card-frame:not(:has(.bf-content-card-footer))) {
372
+ min-block-size: 0;
373
+ padding-block-end: calc(var(--bf-space-2) - (var(--bf-border-width) * 2));
374
+ }
375
+ }
376
+
377
+ @container bf-content-card (width >= 28.75rem) {
378
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-frame) {
379
+ column-gap: var(--bf-space-2);
380
+ flex-direction: row;
381
+ min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
382
+ padding: var(--bf-space-2) var(--bf-space-2) 0;
383
+ }
384
+
385
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6):not(.is-image)) :where(.bf-content-card-frame) {
386
+ min-block-size: calc((var(--bf-space-12) * 2) - (var(--bf-border-width) * 2));
387
+ }
388
+
389
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-media) {
390
+ align-self: stretch;
391
+ inline-size: calc(var(--bf-space-12) * 3);
392
+ padding-block-end: 0;
393
+ }
394
+
395
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-image) {
396
+ aspect-ratio: 16 / 9;
397
+ block-size: auto;
398
+ block-size: calc(var(--bf-space-12) + var(--bf-space-8));
399
+ }
400
+
401
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-body) {
402
+ padding-inline: 0;
403
+ }
404
+
405
+ :where(.bf-theme) :where(.bf-content-card:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-footer-inner) {
406
+ padding-inline: 0;
407
+ }
408
+
409
+ /* An explicit image-top modifier wins after the horizontal rules. */
410
+ :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-frame) {
411
+ flex-direction: column;
412
+ min-block-size: calc((var(--bf-space-12) * 4) - (var(--bf-border-width) * 2));
413
+ padding: 0;
414
+ }
415
+
416
+ :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-media) {
417
+ inline-size: 100%;
418
+ padding-block-end: var(--bf-space-2);
419
+ }
420
+
421
+ :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-image) {
422
+ aspect-ratio: 16 / 9;
423
+ block-size: auto;
424
+ block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
425
+ }
426
+
427
+ :where(.bf-theme) :where(.bf-content-card.is-image-top:is(.is-cols-4, .is-cols-6)) :where(.bf-content-card-body, .bf-content-card-footer-inner) {
428
+ padding-inline: var(--bf-space-2);
429
+ }
430
+ }
431
+
432
+ @container bf-content-card (width >= 60rem) {
433
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8.is-image) :where(.bf-content-card-frame) {
434
+ display: grid;
435
+ grid-template-columns: repeat(2, minmax(0, 1fr));
436
+ min-block-size: calc((var(--bf-space-12) * 3 + var(--bf-space-8)) - (var(--bf-border-width) * 2));
437
+ padding: 0;
438
+ }
439
+
440
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-content) {
441
+ grid-column: 1;
442
+ grid-row: 1;
443
+ }
444
+
445
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-body) {
446
+ padding-block-start: var(--bf-space-2);
447
+ }
448
+
449
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-media) {
450
+ block-size: 100%;
451
+ grid-column: 2;
452
+ grid-row: 1;
453
+ padding: var(--bf-space-1) var(--bf-space-1) 0;
454
+ }
455
+
456
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-image) {
457
+ aspect-ratio: auto;
458
+ block-size: 100%;
459
+ }
460
+
461
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-description) {
462
+ -webkit-line-clamp: 3;
463
+ line-clamp: 3;
464
+ margin-block-end: 0;
465
+ }
466
+
467
+ :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8.is-image) :where(.bf-content-card-frame) {
468
+ display: flex;
469
+ flex-direction: column;
470
+ }
471
+
472
+ :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8) :where(.bf-content-card-media) {
473
+ block-size: auto;
474
+ padding: 0 0 var(--bf-space-2);
475
+ }
476
+
477
+ :where(.bf-theme) :where(.bf-content-card.is-image-top.is-cols-8) :where(.bf-content-card-image) {
478
+ aspect-ratio: 16 / 9;
479
+ block-size: auto;
480
+ block-size: round(up, calc(100cqi * 9 / 16), var(--bf-baseline));
481
+ }
482
+ }
483
+
484
+ @media (38.75rem <= width < 64.75rem) {
485
+ :where(.bf-theme) :where(.bf-content-card.is-cols-2) :where(.bf-content-card-author-date),
486
+ :where(.bf-theme) :where(.bf-content-card.is-cols-6) :where(.bf-content-card-author-date) {
487
+ display: none;
488
+ }
489
+
490
+ :where(.bf-theme) :where(.bf-content-card.is-cols-8) :where(.bf-content-card-main-link) {
491
+ -webkit-line-clamp: 2;
492
+ line-clamp: 2;
493
+ }
494
+ }
495
+
496
+ /* Vanilla swaps primary copy for the optional description on desktop. Only
497
+ hover or focus of the main action triggers the swap; focusing a nested
498
+ author/footer action never makes that focused control disappear. */
499
+ @media (width >= 64.75rem) {
500
+ :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):hover) :where(.bf-content-card-primary),
501
+ :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):has(.bf-content-card-main-link:focus-visible)) :where(.bf-content-card-primary) {
502
+ opacity: 0;
503
+ }
504
+
505
+ :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):hover) :where(.bf-content-card-description-panel),
506
+ :where(.bf-theme) :where(.bf-content-card.is-description-reveal:not(.is-cols-8):has(.bf-content-card-main-link:focus-visible)) :where(.bf-content-card-description-panel) {
507
+ opacity: 1;
508
+ transform: translateY(0);
509
+ }
510
+ }
511
+
512
+ @media (prefers-reduced-motion: reduce) {
513
+ :where(.bf-theme) :where(.bf-content-card, .bf-content-card-primary, .bf-content-card-description-panel) {
514
+ transition-duration: 0.01ms;
515
+ }
516
+ }
516
517
  `;
517
518
  }