baseline-foundry 0.1.4 → 0.1.6

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 +16 -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 +57 -10
  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 +108 -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 +6 -8
  35. package/dist/css-components/panel.js +12 -12
  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 -7
  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 +243 -124
  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 +1005 -563
  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 +1046 -593
  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 +1036 -587
  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 +1036 -587
  66. package/dist/surfaces.json +17 -17
  67. package/dist/tiers/app/styles.css +1046 -593
  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 +1037 -588
  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 +1036 -587
  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 +1042 -593
  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.6/baseline-foundry-0.1.6.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,24 @@ ${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
+ }
17
+
18
+ /* Preserve the public nested fit after the preset's general typography pass.
19
+ The modifier remains explicit and zero-specificity in every app scope. */
20
+ ${scoped(" :where(.bf-status-label.is-nested, .bf-chip.is-nested)")} {
21
+ line-height: var(--bf-nested-auxiliary-line-height);
16
22
  }
17
23
 
18
24
  ${scoped(" :where(.bf-input, .bf-button, .bf-button.is-base)")} {
19
25
  font-family: inherit;
20
- font-size: 0.875rem;
26
+ font-size: var(--bf-body-font-size);
21
27
  font-style: normal;
22
28
  font-weight: 400;
23
- line-height: 1.25rem;
29
+ line-height: var(--bf-body-line-height);
24
30
  }
25
31
 
26
32
  ${scoped(" :where(.bf-application)")} {
@@ -30,7 +36,7 @@ ${scoped(" :where(.bf-application)")} {
30
36
  ${scoped(" :where(.bf-navigation-drawer)")},
31
37
  ${scoped(" :where(.bf-navigation:not(.is-collapsed)) > :where(.bf-navigation-drawer)")},
32
38
  ${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);
39
+ box-shadow: 0 0.625rem 1.25rem rgba(0, 0, 0, 0.12), 0 0 0.1875rem rgba(0, 0, 0, 0.12);
34
40
  }
35
41
 
36
42
  ${scoped(" :where(.bf-panel-header)")} {
@@ -49,6 +55,11 @@ ${scoped(" :where(.bf-navigation-bar) :where(.bf-panel-header)")} {
49
55
  padding-block-end: calc(var(--bf-panel-padding-block) - var(--bf-border-width));
50
56
  }
51
57
 
58
+ ${scoped(" :where(.bf-navigation-bar.is-responsive) :where(.bf-panel-header.is-navigation-brand)")} {
59
+ gap: calc(var(--bf-baseline) * 2);
60
+ padding-block: 0;
61
+ }
62
+
52
63
  ${scoped(" :where(.bf-panel-controls)")} {
53
64
  gap: calc(var(--bf-baseline) * 1.5);
54
65
  }
@@ -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);
@@ -10,21 +10,23 @@ export function chipBadgeStatusCss(options) {
10
10
  ${bodyTypeStyles} align-items: baseline;
11
11
  background-color: var(--bf-ui-chip-background);
12
12
  border: var(--bf-border-width) solid var(--bf-ui-chip-border);
13
- border-radius: 1rem;
13
+ border-radius: var(--bf-ui-chip-radius);
14
14
  color: var(--bf-color-text-default);
15
15
  display: inline-flex;
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;
@@ -158,5 +173,37 @@ ${bodyTypeStyles} margin: 0;
158
173
  --bf-ui-status-background: var(--bf-color-border-negative);
159
174
  --bf-ui-status-color: var(--bf-color-button-negative-text);
160
175
  }
176
+
177
+ /* Nested auxiliary surfaces fit a body-sized flex/grid host instead of
178
+ carrying a second standalone occupied-row contract. This modifier is
179
+ explicit so component density never changes merely because of ancestry. */
180
+ :where(.bf-theme) :where(.bf-chip.is-nested, .bf-status-label.is-nested) {
181
+ line-height: var(--bf-nested-auxiliary-line-height);
182
+ margin-block: 0;
183
+ padding-block: var(--bf-nested-auxiliary-padding-block);
184
+ }
185
+
186
+ :where(.bf-theme) :where(.bf-chip.is-nested) {
187
+ border: 0;
188
+ box-shadow: inset 0 0 0 var(--bf-border-width) var(--bf-ui-chip-border);
189
+ }
190
+
191
+ :where(.bf-theme) :where(.bf-chip.is-nested:hover) {
192
+ box-shadow: inset 0 0 0 var(--bf-border-width) var(--bf-ui-chip-border-hover);
193
+ }
194
+
195
+ :where(.bf-theme) :where(.bf-chip.is-nested:is(:active, [aria-pressed='true'], .is-selected)) {
196
+ box-shadow: inset 0 0 0 var(--bf-border-width) var(--bf-ui-chip-border-active);
197
+ }
198
+
199
+ :where(.bf-theme) :where(.bf-status-label.is-nested) {
200
+ border-block-width: 0;
201
+ }
202
+
203
+ :where(.bf-theme) :where(.bf-badge.is-nested) {
204
+ align-self: center;
205
+ line-height: var(--bf-nested-auxiliary-line-height);
206
+ vertical-align: middle;
207
+ }
161
208
  `;
162
209
  }
@@ -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