baseline-foundry 0.1.4 → 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 (82) hide show
  1. package/README.md +17 -9
  2. package/config/experiments/ibm-plex-engine-smoke.json +1 -1
  3. package/config/experiments/ubuntu-engine-smoke.json +1 -1
  4. package/config/foundation-theme.json +1 -1
  5. package/config/tiers/app.json +6 -6
  6. package/config/tiers/documentation.json +2 -2
  7. package/config/tiers/editorial.json +1 -1
  8. package/config/tiers/os.json +6 -6
  9. package/dist/baseline-grid-overlay.js +2 -2
  10. package/dist/build.js +4 -4
  11. package/dist/code-snippet.js +1 -1
  12. package/dist/css-app-tier.js +10 -5
  13. package/dist/css-components/article-pagination.js +9 -8
  14. package/dist/css-components/button-actions.js +24 -4
  15. package/dist/css-components/cards-options.js +8 -8
  16. package/dist/css-components/chip-badge-status.d.ts +0 -3
  17. package/dist/css-components/chip-badge-status.js +24 -9
  18. package/dist/css-components/content-card.d.ts +7 -7
  19. package/dist/css-components/content-card.js +17 -16
  20. package/dist/css-components/control-row.d.ts +1 -1
  21. package/dist/css-components/control-row.js +1 -1
  22. package/dist/css-components/document-navigation.js +66 -29
  23. package/dist/css-components/editorial-content.js +1 -1
  24. package/dist/css-components/interactive-feedback.js +50 -28
  25. package/dist/css-components/interactive-tables.js +13 -8
  26. package/dist/css-components/legacy-navigation.d.ts +0 -1
  27. package/dist/css-components/legacy-navigation.js +85 -32
  28. package/dist/css-components/linked-logo-site-layout.d.ts +3 -3
  29. package/dist/css-components/linked-logo-site-layout.js +17 -20
  30. package/dist/css-components/list-tree.js +21 -19
  31. package/dist/css-components/list.js +9 -7
  32. package/dist/css-components/logo-media.d.ts +6 -6
  33. package/dist/css-components/logo-media.js +38 -27
  34. package/dist/css-components/navigation-layout.js +4 -4
  35. package/dist/css-components/panel.js +12 -8
  36. package/dist/css-components/search-box-and-filter.d.ts +0 -1
  37. package/dist/css-components/search-box-and-filter.js +18 -19
  38. package/dist/css-components/sites-editorial-ports.d.ts +3 -4
  39. package/dist/css-components/sites-editorial-ports.js +61 -29
  40. package/dist/css-components/sites-foundation.js +15 -19
  41. package/dist/css-components/sites-rich-lists.d.ts +5 -5
  42. package/dist/css-components/sites-rich-lists.js +26 -36
  43. package/dist/css-components/static-content-ports.d.ts +3 -3
  44. package/dist/css-components/static-content-ports.js +51 -37
  45. package/dist/css-components/tab-section.d.ts +3 -3
  46. package/dist/css-components/tab-section.js +34 -26
  47. package/dist/css-components/table.js +4 -3
  48. package/dist/css-components/tabs-choice-breadcrumbs.js +25 -21
  49. package/dist/css-components/tiered-list-equal-height-row.js +10 -10
  50. package/dist/css-components.js +189 -111
  51. package/dist/css-grid.d.ts +1 -1
  52. package/dist/css-grid.js +18 -8
  53. package/dist/css.js +94 -18
  54. package/dist/experiments/ibm-plex-engine-smoke/styles.css +894 -538
  55. package/dist/experiments/ibm-plex-engine-smoke/surfaces.json +2 -2
  56. package/dist/experiments/ibm-plex-engine-smoke/tokens.json +1 -1
  57. package/dist/in-page-navigation.js +1 -1
  58. package/dist/presets/app-tier/styles.css +928 -568
  59. package/dist/presets/app-tier/surfaces.json +17 -17
  60. package/dist/presets/app-tier/tokens.json +7 -7
  61. package/dist/presets/prose/styles.css +919 -562
  62. package/dist/presets/prose/surfaces.json +17 -17
  63. package/dist/presets/prose/tokens.json +1 -1
  64. package/dist/resizable-aside.js +12 -4
  65. package/dist/styles.css +919 -562
  66. package/dist/surfaces.json +17 -17
  67. package/dist/tiers/app/styles.css +928 -568
  68. package/dist/tiers/app/surfaces.json +17 -17
  69. package/dist/tiers/app/tokens.json +7 -7
  70. package/dist/tiers/documentation/styles.css +920 -563
  71. package/dist/tiers/documentation/surfaces.json +17 -17
  72. package/dist/tiers/documentation/tokens.json +2 -2
  73. package/dist/tiers/editorial/styles.css +919 -562
  74. package/dist/tiers/editorial/surfaces.json +17 -17
  75. package/dist/tiers/editorial/tokens.json +1 -1
  76. package/dist/tiers/os/styles.css +925 -568
  77. package/dist/tiers/os/surfaces.json +17 -17
  78. package/dist/tiers/os/tokens.json +7 -7
  79. package/dist/tokens.json +1 -1
  80. package/dist/types.d.ts +1 -1
  81. package/docs/publishing.md +1 -1
  82. package/package.json +2 -2
package/README.md CHANGED
@@ -115,7 +115,7 @@ The verified GitHub release artifact remains available as a fallback for
115
115
  environments that cannot reach the npm registry:
116
116
 
117
117
  ```bash
118
- npm install https://github.com/lyubomir-popov/baseline-foundry/releases/download/v0.1.3/baseline-foundry-0.1.3.tgz
118
+ npm install https://github.com/lyubomir-popov/baseline-foundry/releases/download/v0.1.5/baseline-foundry-0.1.5.tgz
119
119
  ```
120
120
 
121
121
  Use the attached `.tgz`, not the GitHub source archive: generated `dist/`
@@ -188,7 +188,10 @@ The demo runs at:
188
188
  - [http://127.0.0.1:4174/demo/patterns/index.html](http://127.0.0.1:4174/demo/patterns/index.html) — Patterns, site compositions, recipes, layouts, and documented exclusions
189
189
  - [http://127.0.0.1:4174/demo/components/engine-illustration.html](http://127.0.0.1:4174/demo/components/engine-illustration.html) — Three-way raw / compensated / cap comparison
190
190
 
191
- Standalone historical Canonical example batches also live under `examples/grid/` and `examples/spacing/`. Each family has one shared stylesheet (`grid-examples.css` / `spacing-examples.css`); current decisions live in the active Spec Kit package rather than one-off root prompts.
191
+ Standalone grid examples live under `examples/grid/` and share
192
+ `grid-examples.css`. Spacing behavior is documented by the living spacing
193
+ chapter and verified on the component or pattern that owns each relationship;
194
+ the catalog does not expose separate diagnostic spacing pages.
192
195
 
193
196
  ## Component and pattern QA
194
197
 
@@ -268,15 +271,20 @@ into a broader tier set.
268
271
 
269
272
  The default theme uses Ubuntu Sans Variable and generates metric-driven typography tokens, spacing tokens, layout values, component density tokens, and a published surface manifest. Four first-class tiers plus two legacy preset aliases:
270
273
 
271
- | Tier/Preset | Purpose |
272
- |---|---|
273
- | `editorial` | Root default, widest long-form composition |
274
- | `documentation` | Tighter chapter-reading tier |
275
- | `app` | Canonical-facing application chrome |
276
- | `os` | Dense OS-style tier with metric alignment and compact control geometry |
274
+ | Tier/Preset | Content cap | Purpose |
275
+ |---|---:|---|
276
+ | `editorial` | `90rem` | Root default, widest long-form composition |
277
+ | `documentation` | `80rem` | Tighter chapter-reading tier |
278
+ | `app` | `60rem` | Fluid application chrome with a cap only on explicit `bf-fixed-width` rows |
279
+ | `os` | `60rem` | Dense OS-style tier with metric alignment and compact control geometry |
277
280
 
278
281
  Legacy aliases: `prose` → editorial, `app-tier` → app.
279
282
 
283
+ The caps are a non-increasing density progression (`90 >= 80 >= 60 >= 60`).
284
+ App `.bf-page` and application grids remain uncapped and fluid; the App/OS
285
+ value governs only explicit bounded content. Tier and density are currently one
286
+ coupled choice, not independent axes.
287
+
280
288
  Independent surface contract:
281
289
 
282
290
  - each built-in tier emits a complete scoped token surface instead of inheriting editorial defaults through diffs
@@ -487,7 +495,7 @@ Example sketch for a downstream Ubuntu Sans theme:
487
495
  "pageMarginBaselineUnits": 2
488
496
  },
489
497
  "components": {
490
- "borderWidthPx": 1,
498
+ "borderWidthRem": 0.0625,
491
499
  "radiusRem": 0,
492
500
  "controlBlockPaddingRem": 0.5,
493
501
  "controlCompactBlockPaddingRem": 0.25,
@@ -101,7 +101,7 @@
101
101
  "pageMarginBaselineUnits": 3
102
102
  },
103
103
  "components": {
104
- "borderWidthPx": 1,
104
+ "borderWidthRem": 0.0625,
105
105
  "radiusRem": 0,
106
106
  "controlBlockPaddingRem": 0.5,
107
107
  "controlCompactBlockPaddingRem": 0.25,
@@ -101,7 +101,7 @@
101
101
  "pageMarginBaselineUnits": 3
102
102
  },
103
103
  "components": {
104
- "borderWidthPx": 1,
104
+ "borderWidthRem": 0.0625,
105
105
  "radiusRem": 0,
106
106
  "controlBlockPaddingRem": 0.5,
107
107
  "controlCompactBlockPaddingRem": 0.25,
@@ -103,7 +103,7 @@
103
103
  "pageMarginBaselineUnits": 2
104
104
  },
105
105
  "components": {
106
- "borderWidthPx": 1,
106
+ "borderWidthRem": 0.0625,
107
107
  "radiusRem": 0,
108
108
  "controlBlockPaddingRem": 0.5,
109
109
  "controlCompactBlockPaddingRem": 0.25,
@@ -92,29 +92,29 @@
92
92
  "h6": "h6"
93
93
  },
94
94
  "layout": {
95
- "contentMaxWidthRem": 90,
95
+ "contentMaxWidthRem": 60,
96
96
  "contentPaddingInlineRem": 1,
97
97
  "measureRem": 40,
98
98
  "sectionSpaceBaselineUnits": 4,
99
99
  "sectionSpaceShallowBaselineUnits": 2,
100
100
  "sectionSpaceDeepBaselineUnits": 8,
101
- "stripSpaceBaselineUnits": 16,
101
+ "stripSpaceBaselineUnits": 12,
102
102
  "gridGapInlineBaselineUnits": 6,
103
103
  "gridGapBlockBaselineUnits": 6,
104
104
  "pageMarginBaselineUnits": 8
105
105
  },
106
106
  "components": {
107
- "borderWidthPx": 1,
107
+ "borderWidthRem": 0.0625,
108
108
  "radiusRem": 0.125,
109
109
  "controlBlockPaddingRem": 0.5,
110
110
  "controlCompactBlockPaddingRem": 0.375,
111
111
  "controlInlinePaddingRem": 1,
112
- "controlInlinePaddingActionRem": 0.5,
112
+ "controlInlinePaddingActionRem": 1,
113
113
  "controlInlinePaddingFieldRem": 0.25,
114
114
  "controlVisualSizeRem": 1,
115
115
  "fieldGapBaselineUnits": 2,
116
- "panelPaddingInlineBaselineUnits": 6,
117
- "panelPaddingBlockBaselineUnits": 6,
116
+ "panelPaddingInlineBaselineUnits": 3,
117
+ "panelPaddingBlockBaselineUnits": 3,
118
118
  "accordionIndentBaselineUnits": 6
119
119
  }
120
120
  }
@@ -92,7 +92,7 @@
92
92
  "h6": "h6"
93
93
  },
94
94
  "layout": {
95
- "contentMaxWidthRem": 96,
95
+ "contentMaxWidthRem": 80,
96
96
  "contentPaddingInlineRem": 1.5,
97
97
  "measureRem": 38,
98
98
  "sectionSpaceBaselineUnits": 12,
@@ -104,7 +104,7 @@
104
104
  "pageMarginBaselineUnits": 6
105
105
  },
106
106
  "components": {
107
- "borderWidthPx": 1,
107
+ "borderWidthRem": 0.0625,
108
108
  "radiusRem": 0,
109
109
  "controlBlockPaddingRem": 0.5,
110
110
  "controlCompactBlockPaddingRem": 0.375,
@@ -104,7 +104,7 @@
104
104
  "pageMarginBaselineUnits": 2
105
105
  },
106
106
  "components": {
107
- "borderWidthPx": 1,
107
+ "borderWidthRem": 0.0625,
108
108
  "radiusRem": 0,
109
109
  "controlBlockPaddingRem": 0.5,
110
110
  "controlCompactBlockPaddingRem": 0.25,
@@ -92,29 +92,29 @@
92
92
  "h6": "h6"
93
93
  },
94
94
  "layout": {
95
- "contentMaxWidthRem": 67.5,
95
+ "contentMaxWidthRem": 60,
96
96
  "contentPaddingInlineRem": 0.75,
97
97
  "measureRem": 30,
98
98
  "sectionSpaceBaselineUnits": 12,
99
99
  "sectionSpaceShallowBaselineUnits": 6,
100
100
  "sectionSpaceDeepBaselineUnits": 24,
101
- "stripSpaceBaselineUnits": 12,
101
+ "stripSpaceBaselineUnits": 8,
102
102
  "gridGapInlineBaselineUnits": 4,
103
103
  "gridGapBlockBaselineUnits": 4,
104
104
  "pageMarginBaselineUnits": 4
105
105
  },
106
106
  "components": {
107
- "borderWidthPx": 1,
107
+ "borderWidthRem": 0.0625,
108
108
  "radiusRem": 0,
109
109
  "controlBlockPaddingRem": 0.375,
110
110
  "controlCompactBlockPaddingRem": 0.25,
111
111
  "controlInlinePaddingRem": 0.75,
112
- "controlInlinePaddingActionRem": 0.5,
112
+ "controlInlinePaddingActionRem": 1,
113
113
  "controlInlinePaddingFieldRem": 0.25,
114
114
  "controlVisualSizeRem": 0.75,
115
115
  "fieldGapBaselineUnits": 1,
116
- "panelPaddingInlineBaselineUnits": 4,
117
- "panelPaddingBlockBaselineUnits": 4,
116
+ "panelPaddingInlineBaselineUnits": 2,
117
+ "panelPaddingBlockBaselineUnits": 2,
118
118
  "accordionIndentBaselineUnits": 3
119
119
  }
120
120
  }
@@ -12,8 +12,8 @@ export function generateBaselineGridOverlayCss(options) {
12
12
  background-image: linear-gradient(
13
13
  to top,
14
14
  var(--bf-baseline-grid-color),
15
- var(--bf-baseline-grid-color) 1px,
16
- transparent 1px,
15
+ var(--bf-baseline-grid-color) 0.0625rem,
16
+ transparent 0.0625rem,
17
17
  transparent
18
18
  );
19
19
  background-size: 100% var(--bf-baseline-grid-size);
package/dist/build.js CHANGED
@@ -50,7 +50,7 @@ const REQUIRED_LAYOUT_FIELDS = [
50
50
  "pageMarginBaselineUnits"
51
51
  ];
52
52
  const REQUIRED_COMPONENT_FIELDS = [
53
- "borderWidthPx",
53
+ "borderWidthRem",
54
54
  "radiusRem",
55
55
  "controlBlockPaddingRem",
56
56
  "controlInlinePaddingRem",
@@ -209,9 +209,9 @@ function buildComponentTokens(config) {
209
209
  const controlInlinePaddingActionRem = config.components.controlInlinePaddingActionRem ?? config.components.controlInlinePaddingRem;
210
210
  const controlInlinePaddingFieldRem = config.components.controlInlinePaddingFieldRem ?? (controlInlinePaddingActionRem / 2);
211
211
  return {
212
- borderWidth: `${config.components.borderWidthPx}px`,
213
- // Vanilla's shared $bar-thickness: 3px at a 16px root, expressed in rem
214
- // so emphasis bars scale with root text sizing while thin borders do not.
212
+ borderWidth: toRem(config.components.borderWidthRem),
213
+ // Vanilla's shared $bar-thickness is represented as 0.1875rem so emphasis
214
+ // bars and thin borders both scale with root text sizing.
215
215
  barThickness: toRem(3 / 16),
216
216
  radius: toRem(config.components.radiusRem),
217
217
  controlBlockPadding: toRem(config.components.controlBlockPaddingRem),
@@ -23,7 +23,7 @@ async function copySnippetText(copyBlock) {
23
23
  textarea.value = text;
24
24
  textarea.setAttribute("readonly", "");
25
25
  textarea.style.position = "fixed";
26
- textarea.style.inset = "-9999px";
26
+ textarea.style.inset = "-624.9375rem";
27
27
  document.body.append(textarea);
28
28
  textarea.select();
29
29
  try {
@@ -9,18 +9,18 @@ ${scoped()} {
9
9
 
10
10
  ${scoped(" :where(.bf-form-label, .bf-form-help, .bf-button, .bf-button.is-base, .bf-status-label, .bf-chip, .bf-checkbox-label, .bf-radio-label, .bf-tabs-link, .bf-accordion-tab, .bf-validation-message)")} {
11
11
  font-family: inherit;
12
- font-size: 0.875rem;
12
+ font-size: var(--bf-body-font-size);
13
13
  font-style: normal;
14
14
  font-weight: 400;
15
- line-height: 1.25rem;
15
+ line-height: var(--bf-body-line-height);
16
16
  }
17
17
 
18
18
  ${scoped(" :where(.bf-input, .bf-button, .bf-button.is-base)")} {
19
19
  font-family: inherit;
20
- font-size: 0.875rem;
20
+ font-size: var(--bf-body-font-size);
21
21
  font-style: normal;
22
22
  font-weight: 400;
23
- line-height: 1.25rem;
23
+ line-height: var(--bf-body-line-height);
24
24
  }
25
25
 
26
26
  ${scoped(" :where(.bf-application)")} {
@@ -30,7 +30,7 @@ ${scoped(" :where(.bf-application)")} {
30
30
  ${scoped(" :where(.bf-navigation-drawer)")},
31
31
  ${scoped(" :where(.bf-navigation:not(.is-collapsed)) > :where(.bf-navigation-drawer)")},
32
32
  ${scoped(" :where(.bf-aside.is-overlay, .bf-aside.is-drawer)")} {
33
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.12), 0 0 3px rgba(0, 0, 0, 0.12);
33
+ box-shadow: 0 0.625rem 1.25rem rgba(0, 0, 0, 0.12), 0 0 0.1875rem rgba(0, 0, 0, 0.12);
34
34
  }
35
35
 
36
36
  ${scoped(" :where(.bf-panel-header)")} {
@@ -49,6 +49,11 @@ ${scoped(" :where(.bf-navigation-bar) :where(.bf-panel-header)")} {
49
49
  padding-block-end: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
50
50
  }
51
51
 
52
+ ${scoped(" :where(.bf-navigation-bar.is-responsive) :where(.bf-panel-header.is-navigation-brand)")} {
53
+ gap: calc(var(--bf-baseline) * 2);
54
+ padding-block: 0;
55
+ }
56
+
52
57
  ${scoped(" :where(.bf-panel-controls)")} {
53
58
  gap: calc(var(--bf-baseline) * 1.5);
54
59
  }
@@ -12,11 +12,11 @@ export function articlePaginationCss(options) {
12
12
  container-type: inline-size;
13
13
  display: grid;
14
14
  grid-template-columns: auto minmax(0, 1fr);
15
- margin-block-end: var(--bf-section-space-shallow);
15
+ margin: 0;
16
16
  min-inline-size: 0;
17
17
  }
18
18
 
19
- :where(.bf-theme) :where(.bf-article-pagination-link) {
19
+ :where(.bf-theme) :where(a.bf-article-pagination-link) {
20
20
  background-color: var(--bf-color-background-default);
21
21
  border: var(--bf-border-width) solid transparent;
22
22
  box-sizing: border-box;
@@ -32,8 +32,9 @@ export function articlePaginationCss(options) {
32
32
  text-decoration: none;
33
33
  }
34
34
 
35
- :where(.bf-theme) :where(.bf-article-pagination-link:hover) {
35
+ :where(.bf-theme) :where(a.bf-article-pagination-link:hover) {
36
36
  background-color: var(--bf-color-background-hover);
37
+ text-decoration: none;
37
38
  }
38
39
 
39
40
  :where(.bf-theme) :where(.bf-article-pagination-link:focus:not(:focus-visible)) {
@@ -41,8 +42,8 @@ export function articlePaginationCss(options) {
41
42
  }
42
43
 
43
44
  :where(.bf-theme) :where(.bf-article-pagination-link:focus-visible) {
44
- outline: 2px solid var(--bf-color-focus);
45
- outline-offset: 2px;
45
+ outline: 0.125rem solid var(--bf-color-focus);
46
+ outline-offset: 0.125rem;
46
47
  }
47
48
 
48
49
  :where(.bf-theme) :where(.bf-article-pagination-link.is-previous) {
@@ -134,12 +135,12 @@ ${titleTypeStyles} color: inherit;
134
135
 
135
136
  :where(.bf-theme) :where(.bf-article-pagination-link.is-previous:not(:only-child) .bf-article-pagination-label),
136
137
  :where(.bf-theme) :where(.bf-article-pagination-link.is-previous:not(:only-child) .bf-article-pagination-title) {
137
- block-size: 1px;
138
+ block-size: 0.0625rem;
138
139
  border: 0;
139
140
  clip: rect(0 0 0 0);
140
141
  clip-path: inset(50%);
141
- inline-size: 1px;
142
- margin: -1px;
142
+ inline-size: 0.0625rem;
143
+ margin: -0.0625rem;
143
144
  overflow: hidden;
144
145
  padding: 0;
145
146
  position: absolute;
@@ -9,7 +9,7 @@ ${bodyTypeStyles} appearance: none;
9
9
  cursor: pointer;
10
10
  display: inline-block;
11
11
  margin-bottom: ${buttonMarginBottom};
12
- ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action);
12
+ ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action-bordered);
13
13
  text-align: center;
14
14
  text-decoration: none;
15
15
  }
@@ -27,6 +27,13 @@ ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action);
27
27
  background-color: var(--bf-color-background-hover);
28
28
  }
29
29
 
30
+ /* Anchor buttons are controls, not prose links. Qualifying the element and
31
+ * its interaction states prevents the generic anchor underline from leaking
32
+ * through while leaving the explicit is-link variant unchanged. */
33
+ :where(.bf-theme) :where(a.bf-button:not(.is-link):is(:hover, :active)) {
34
+ text-decoration: none;
35
+ }
36
+
30
37
  :where(.bf-theme) :where(.bf-button:not(.is-base):is(:active, [aria-pressed='true'])) {
31
38
  background-color: var(--bf-color-background-active);
32
39
  }
@@ -36,8 +43,8 @@ ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action);
36
43
  }
37
44
 
38
45
  :where(.bf-theme) :where(.bf-button, .bf-button.is-base):focus-visible {
39
- outline: 2px solid var(--bf-color-focus);
40
- outline-offset: 2px;
46
+ outline: 0.125rem solid var(--bf-color-focus);
47
+ outline-offset: 0.125rem;
41
48
  }
42
49
 
43
50
  /* ------------------------------------------------------------------ */
@@ -109,7 +116,7 @@ ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action);
109
116
  background-color: transparent;
110
117
  color: var(--bf-color-link-default);
111
118
  text-decoration: underline;
112
- text-decoration-thickness: 1px;
119
+ text-decoration-thickness: 0.0625rem;
113
120
  text-underline-offset: 0.075em;
114
121
  }
115
122
 
@@ -136,6 +143,19 @@ ${buttonPadding} padding-inline: var(--bf-control-inline-padding-action);
136
143
  justify-content: center;
137
144
  }
138
145
 
146
+ /* An icon-only flex button has no text line box to preserve the occupied
147
+ * control rhythm. A zero-width metric strut restores the active body line
148
+ * without imposing a target block size or changing icon/label spacing. */
149
+ :where(.bf-theme) :where(.bf-button.is-icon:not(:has(.bf-button-label))) {
150
+ column-gap: 0;
151
+ }
152
+
153
+ :where(.bf-theme) :where(.bf-button.is-icon:not(:has(.bf-button-label)))::before {
154
+ block-size: var(--bf-body-line-height);
155
+ content: "";
156
+ inline-size: 0;
157
+ }
158
+
139
159
  :where(.bf-theme) :where(.bf-button-label) {
140
160
  min-inline-size: 0;
141
161
  }
@@ -15,7 +15,7 @@ export function cardsOptionsCss(options) {
15
15
  overflow: auto;
16
16
  padding-block-end: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
17
17
  padding-block-start: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
18
- padding-inline: var(--bf-panel-padding-inline);
18
+ padding-inline: var(--bf-component-inline-inset-continuation);
19
19
  }
20
20
 
21
21
  :where(.bf-theme) :where(.bf-card.is-highlighted) {
@@ -40,7 +40,7 @@ export function cardsOptionsCss(options) {
40
40
 
41
41
  :where(.bf-theme) :where(a.bf-card:hover, a.bf-card.is-highlighted:hover, a.bf-card.is-overlay:hover, a.bf-card.is-muted:hover) {
42
42
  border-color: var(--bf-color-focus);
43
- transform: translateY(-1px);
43
+ transform: translateY(-0.0625rem);
44
44
  }
45
45
 
46
46
  :where(.bf-theme) :where(a.bf-card:focus:not(:focus-visible), a.bf-card.is-highlighted:focus:not(:focus-visible), a.bf-card.is-overlay:focus:not(:focus-visible), a.bf-card.is-muted:focus:not(:focus-visible)) {
@@ -48,8 +48,8 @@ export function cardsOptionsCss(options) {
48
48
  }
49
49
 
50
50
  :where(.bf-theme) :where(a.bf-card:focus-visible, a.bf-card.is-highlighted:focus-visible, a.bf-card.is-overlay:focus-visible, a.bf-card.is-muted:focus-visible) {
51
- outline: 2px solid var(--bf-color-focus);
52
- outline-offset: -2px;
51
+ outline: 0.125rem solid var(--bf-color-focus);
52
+ outline-offset: -0.125rem;
53
53
  }
54
54
 
55
55
  :where(.bf-theme) :where(.bf-card.is-preview) {
@@ -132,7 +132,7 @@ export function cardsOptionsCss(options) {
132
132
  min-inline-size: 0;
133
133
  padding-block-end: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
134
134
  padding-block-start: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
135
- padding-inline: var(--bf-panel-padding-inline);
135
+ padding-inline: var(--bf-component-inline-inset-continuation);
136
136
  text-align: left;
137
137
  }
138
138
 
@@ -145,7 +145,7 @@ export function cardsOptionsCss(options) {
145
145
  :where(.bf-theme) :where(button.bf-option-card:hover:not(:disabled)) {
146
146
  background: var(--bf-color-background-hover);
147
147
  border-color: var(--bf-color-focus);
148
- transform: translateY(-1px);
148
+ transform: translateY(-0.0625rem);
149
149
  }
150
150
 
151
151
  :where(.bf-theme) :where(.bf-option-card.is-active),
@@ -156,8 +156,8 @@ export function cardsOptionsCss(options) {
156
156
  }
157
157
 
158
158
  :where(.bf-theme) :where(button.bf-option-card:focus-visible) {
159
- outline: 2px solid var(--bf-color-focus);
160
- outline-offset: -2px;
159
+ outline: 0.125rem solid var(--bf-color-focus);
160
+ outline-offset: -0.125rem;
161
161
  }
162
162
 
163
163
  :where(.bf-theme) :where(.bf-option-card-label) {
@@ -1,9 +1,6 @@
1
1
  type ChipBadgeStatusCssOptions = {
2
2
  bodyCaseTypeStyles: string;
3
3
  bodyLineHeight: string;
4
- bodySelectedStartNudge: string;
5
- h5SelectedEndNudge: string;
6
- h5SelectedStartNudge: string;
7
4
  bodyTypeStyles: string;
8
5
  };
9
6
  export declare function chipBadgeStatusCss(options: ChipBadgeStatusCssOptions): string;
@@ -1,5 +1,5 @@
1
1
  export function chipBadgeStatusCss(options) {
2
- const { bodyCaseTypeStyles, bodyLineHeight, bodySelectedStartNudge, h5SelectedEndNudge, h5SelectedStartNudge, bodyTypeStyles, } = options;
2
+ const { bodyCaseTypeStyles, bodyLineHeight, bodyTypeStyles, } = options;
3
3
  return `:where(.bf-theme) :where(.bf-chip, .bf-chip.is-positive, .bf-chip.is-caution, .bf-chip.is-negative, .bf-chip.is-information) {
4
4
  --bf-ui-chip-border: var(--bf-color-border-neutral);
5
5
  --bf-ui-chip-border-hover: var(--bf-color-border-neutral);
@@ -16,15 +16,17 @@ ${bodyTypeStyles} align-items: baseline;
16
16
  gap: 0;
17
17
  inline-size: fit-content;
18
18
  justify-self: start;
19
- margin: 0 var(--bf-ui-chip-padding-inline) var(--bf-field-gap) 0;
19
+ margin: 0 var(--bf-ui-chip-padding-inline) var(--bf-single-line-row-margin-block-end) 0;
20
20
  max-inline-size: 100%;
21
- min-block-size: var(--bf-ui-chip-block-size);
22
- padding-block: var(--bf-ui-chip-padding-block);
23
- padding-inline: var(--bf-ui-chip-padding-inline);
21
+ padding-block: var(--bf-single-line-row-padding-block);
22
+ padding-inline: max(0rem, calc(var(--bf-ui-chip-padding-inline) - var(--bf-border-width)));
24
23
  position: relative;
25
24
  text-decoration: none;
26
25
  user-select: none;
27
- vertical-align: calc(var(--bf-border-width) - ${bodySelectedStartNudge});
26
+ /* Inline-flex exposes the first text child's baseline. The surrounding
27
+ border-aware row contract now matches buttons instead of inventing a
28
+ second chip-only occupied height. */
29
+ vertical-align: baseline;
28
30
  white-space: nowrap;
29
31
  }
30
32
 
@@ -64,6 +66,15 @@ ${bodyTypeStyles} align-items: baseline;
64
66
  --bf-ui-chip-background-active: var(--bf-color-background-information-active);
65
67
  }
66
68
 
69
+ :where(.bf-theme) :where(.bf-chip.is-borderless) {
70
+ --bf-ui-chip-border: transparent;
71
+ --bf-ui-chip-border-hover: transparent;
72
+ --bf-ui-chip-border-active: transparent;
73
+ --bf-ui-chip-background: transparent;
74
+ --bf-ui-chip-background-hover: transparent;
75
+ --bf-ui-chip-background-active: transparent;
76
+ }
77
+
67
78
  :where(.bf-theme) :where(.bf-chip, .bf-chip.is-positive, .bf-chip.is-caution, .bf-chip.is-negative, .bf-chip.is-information):hover {
68
79
  background-color: var(--bf-ui-chip-background-hover);
69
80
  border-color: var(--bf-ui-chip-border-hover);
@@ -128,11 +139,15 @@ ${bodyTypeStyles} align-items: center;
128
139
  --bf-ui-status-background: color-mix(in srgb, var(--bf-color-background-alt) 70%, black);
129
140
  --bf-ui-status-color: var(--bf-color-button-positive-text);
130
141
  background-color: var(--bf-ui-status-background);
142
+ border-block: var(--bf-border-width) solid transparent;
131
143
  color: var(--bf-ui-status-color);
132
144
  display: inline-block;
133
- ${bodyTypeStyles} margin: 0;
134
- padding-block-end: ${h5SelectedEndNudge};
135
- padding-block-start: ${h5SelectedStartNudge};
145
+ inline-size: fit-content;
146
+ justify-self: start;
147
+ ${bodyTypeStyles} margin: 0 0 var(--bf-single-line-row-margin-block-end);
148
+ /* Status paint is physically symmetric and shares the same occupied block
149
+ as a button; typography still comes from the body role. */
150
+ padding-block: var(--bf-single-line-row-padding-block);
136
151
  padding-inline: var(--bf-ui-chip-padding-inline);
137
152
  text-align: center;
138
153
  text-decoration: none;
@@ -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
@@ -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
@@ -40,7 +40,7 @@ export function contentCardCss() {
40
40
  /* Snap the grid-row wrapper after intrinsic image/copy measurement. Because
41
41
  the card flexes inside it, peers retain Vanilla's equal-height row while
42
42
  the card edge and the following row both land on BF baselines. */
43
- @supports (block-size: calc-size(auto, round(up, size, 1px))) {
43
+ @supports (block-size: calc-size(auto, round(up, size, 0.0625rem))) {
44
44
  :where(.bf-theme) :where(.bf-content-card-wrapper) {
45
45
  block-size: calc-size(auto, round(up, size, var(--bf-baseline)));
46
46
  }
@@ -217,7 +217,7 @@ export function contentCardCss() {
217
217
  text-transform: var(--bf-h1-text-transform);
218
218
  }
219
219
 
220
- :where(.bf-theme) :where(.bf-content-card-main-link) {
220
+ :where(.bf-theme) :where(a.bf-content-card-main-link) {
221
221
  -webkit-box-orient: vertical;
222
222
  -webkit-line-clamp: 3;
223
223
  color: inherit;
@@ -237,7 +237,7 @@ export function contentCardCss() {
237
237
  z-index: 1;
238
238
  }
239
239
 
240
- :where(.bf-theme) :where(.bf-content-card-main-link:is(:hover, :focus, :active, :visited)) {
240
+ :where(.bf-theme) :where(a.bf-content-card-main-link:is(:hover, :focus, :active, :visited)) {
241
241
  color: inherit;
242
242
  text-decoration: none;
243
243
  }
@@ -247,8 +247,8 @@ export function contentCardCss() {
247
247
  }
248
248
 
249
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;
250
+ outline: 0.1875rem solid var(--bf-color-focus);
251
+ outline-offset: 0.125rem;
252
252
  }
253
253
 
254
254
  /* All nested actions sit above the expanded main-link hit area. This includes
@@ -324,6 +324,7 @@ export function contentCardCss() {
324
324
  min-inline-size: 0;
325
325
  overflow-x: auto;
326
326
  padding-block-end: var(--bf-space-1);
327
+ padding-block-start: calc(0.5rem - var(--bf-border-width));
327
328
  padding-inline: var(--bf-space-2);
328
329
  position: relative;
329
330
  scrollbar-width: none;
@@ -361,11 +362,11 @@ export function contentCardCss() {
361
362
 
362
363
  /* Internal geometry responds to the card's allocated width. The card root is
363
364
  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
+ /* Vanilla switches the viewport at 38.75rem/64.75rem. A four-column card is much
365
366
  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. */
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. */
369
370
  @container bf-content-card (width < 28.75rem) {
370
371
  :where(.bf-theme) :where(.bf-content-card-frame:not(:has(.bf-content-card-footer))) {
371
372
  min-block-size: 0;
@@ -1,2 +1,2 @@
1
- /** A wrapping form composition whose children retain their owned spacing. */
1
+ /** A wrapping form composition whose children retain their metric geometry. */
2
2
  export declare function controlRowCss(): string;
@@ -1,4 +1,4 @@
1
- /** A wrapping form composition whose children retain their owned spacing. */
1
+ /** A wrapping form composition whose children retain their metric geometry. */
2
2
  export function controlRowCss() {
3
3
  return `:where(.bf-theme) :where(.bf-control-row) {
4
4
  align-items: end;