@orkestrel/scaffold 0.0.64 → 0.0.65
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.
- package/README.md +11 -1
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +184 -177
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +299 -76
- package/dist/host/agents/skills/enterprise-bootstrap/references/color-modes.md +241 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +83 -36
- package/dist/host/agents/skills/enterprise-bootstrap/references/frontend-design.md +297 -98
- package/dist/host/agents/skills/enterprise-bootstrap/references/inputs.md +25 -14
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +216 -128
- package/dist/host/agents/skills/enterprise-bootstrap/references/responsive-layout.md +187 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +105 -16
- package/dist/host/claude/rules/workspace.md +2 -2
- package/dist/host/claude/settings.json +1 -1
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +10 -9
- package/dist/host/guides/scaffold.md +63 -22
- package/dist/host/manifest.json +25 -13
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +322 -13
- package/dist/src/core/index.cjs +33 -12
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +31 -9
- package/dist/src/core/index.d.ts +31 -9
- package/dist/src/core/index.js +32 -13
- package/dist/src/core/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Color modes and inheritance
|
|
2
|
+
|
|
3
|
+
> Part of the `enterprise-bootstrap` package. Use for foreground ownership, adaptive surfaces,
|
|
4
|
+
> nested themes, and color-mode repairs. Take the contrast bars from [SKILL.md](../SKILL.md).
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Choose the surface](#choose-the-surface)
|
|
9
|
+
- [Text tiers](#text-tiers)
|
|
10
|
+
- [Preserve the cascade](#preserve-the-cascade)
|
|
11
|
+
- [Scope the mode](#scope-the-mode)
|
|
12
|
+
- [Respect component ownership](#respect-component-ownership)
|
|
13
|
+
- [Extend the theme](#extend-the-theme)
|
|
14
|
+
- [Verify the result](#verify-the-result)
|
|
15
|
+
|
|
16
|
+
## Choose the surface
|
|
17
|
+
|
|
18
|
+
Default to inherited text. When ordinary content owns no background, add no foreground override.
|
|
19
|
+
For quiet containers and status, prefer adaptive backgrounds without an added text-color class.
|
|
20
|
+
Treat this as the package default, not a claim that Bootstrap forbids its documented emphasis pairs.
|
|
21
|
+
|
|
22
|
+
| Context | Use | Refuse by default |
|
|
23
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
24
|
+
| Ordinary content | Inherited body or component text | A leaf `color` declaration or `text-*` color chosen without a surface contract |
|
|
25
|
+
| Neutral separation | `bg-body`, `bg-body-secondary`, or `bg-body-tertiary`; inherit text | `bg-white`, `bg-light`, or `bg-dark` as an adaptive surface |
|
|
26
|
+
| Quiet semantic status | `bg-*-subtle`; inherit text and state the meaning in words | Automatically matching the fill with `text-*` or `text-*-emphasis` |
|
|
27
|
+
| Intentional solid or inverse treatment | A component-owned pair, or a measured `text-bg-*` helper | A solid `bg-*` with an unrelated inherited foreground |
|
|
28
|
+
| Selected control | The component's checked/active treatment and foreground | Descendant text or icon colors that override the selected foreground |
|
|
29
|
+
| Secondary information | Spacing and weight first; `text-body-secondary` for a deliberate tier ([Text tiers](#text-tiers)) | Opacity, `text-body-tertiary`, or a neutral grey on a colored fill |
|
|
30
|
+
|
|
31
|
+
Use these quiet treatments inside an ordinary body-color context:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<section class="bg-body-tertiary rounded p-3" aria-labelledby="sync-heading">
|
|
35
|
+
<h2 id="sync-heading" class="h6">Synchronization</h2>
|
|
36
|
+
<p class="mb-0">Updates appear after the next sync.</p>
|
|
37
|
+
</section>
|
|
38
|
+
<span class="d-inline-flex rounded-pill bg-success-subtle px-2 py-1 small fw-semibold">Paid</span>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Measure the inherited result on its actual background. A subtle fill changes only the background;
|
|
42
|
+
it cannot repair a fixed, translucent, or inverse foreground inherited from an ancestor. Remove
|
|
43
|
+
that conflict or establish an owned surface boundary before adding a leaf override.
|
|
44
|
+
|
|
45
|
+
## Text tiers
|
|
46
|
+
|
|
47
|
+
Stock Bootstrap ships two readable text tiers, not three. `--bs-secondary-color` is the body color
|
|
48
|
+
at 75 % alpha and `--bs-tertiary-color` at 50 % alpha, so both composite against whatever sits
|
|
49
|
+
beneath them. Measured on the three stock body surfaces (`bg-body` / `bg-body-tertiary` /
|
|
50
|
+
`bg-body-secondary`) in 5.3.8:
|
|
51
|
+
|
|
52
|
+
| Tier | Light | Dark | 4.5:1 bar |
|
|
53
|
+
| --------------------- | ------------------ | ----------------- | ---------------- |
|
|
54
|
+
| Inherited body | 15.4 / 14.6 / 13.0 | 11.9 / 10.2 / 8.8 | Passes |
|
|
55
|
+
| `text-body-secondary` | 6.8 / 6.6 / 6.2 | 7.3 / 6.5 / 5.8 | Passes |
|
|
56
|
+
| `text-body-tertiary` | 3.1 / 3.1 / 3.0 | 4.1 / 3.8 / 3.5 | Fails everywhere |
|
|
57
|
+
|
|
58
|
+
- Use `text-body-secondary` as the one shipped quiet tier. Use `text-body-tertiary` for decoration
|
|
59
|
+
or disabled chrome only; it never carries a caption, timestamp, or count someone reads.
|
|
60
|
+
- Declare a third readable tier as an opaque token — override `$body-tertiary-color` and
|
|
61
|
+
`$body-tertiary-color-dark`, or add a semantic token — and measure it on each surface it sits on.
|
|
62
|
+
The opaque `text-secondary` (`$gray-600`) clears 4.5:1 only on pure white and does not adapt.
|
|
63
|
+
- More than a dozen component variables consume the translucent secondary color — placeholders,
|
|
64
|
+
`.form-text`, table captions, breadcrumb dividers and the active crumb, toast headers, figure
|
|
65
|
+
captions, list-group action text, several disabled states — and inherit this table.
|
|
66
|
+
- On a colored fill, `text-body-secondary` composites the body color over the hue — grey on color —
|
|
67
|
+
and `text-white-50` or `text-opacity-*` let the fill show through the glyphs. The quiet tone on a
|
|
68
|
+
fill is the same hue at lower contrast: keep the owning component's foreground and quiet a line
|
|
69
|
+
with weight or size, or declare a same-hue token (for the stock blue, the `$blue-200`–`$blue-300`
|
|
70
|
+
region in light mode) through the component's own variable and measure it.
|
|
71
|
+
- For a tinted region, use the shipped same-hue pair: `text-*-emphasis` on `bg-*-subtle` (about
|
|
72
|
+
10:1 for primary in the stock light theme), adapting in both modes. Keep `text-bg-*` solids for
|
|
73
|
+
the primary element.
|
|
74
|
+
|
|
75
|
+
When checking utility behavior, see Bootstrap's [Background](https://getbootstrap.com/docs/5.3/utilities/background/)
|
|
76
|
+
and [Colors](https://getbootstrap.com/docs/5.3/utilities/colors/) references. Distinguish the
|
|
77
|
+
adaptive families from the original contextual families:
|
|
78
|
+
|
|
79
|
+
- Use `bg-*-subtle`, `border-*-subtle`, and body-role variables for mode-aware surfaces and boundaries.
|
|
80
|
+
Measure a required control boundary separately; a subtle border is not a focus treatment.
|
|
81
|
+
- Treat original contextual `bg-primary`, `text-primary`, and their semantic siblings as
|
|
82
|
+
non-adaptive in stock 5.3. Treat `bg-light`, `bg-dark`, `text-light`, and `text-dark` the same way.
|
|
83
|
+
Do not confuse `bg-secondary` with `bg-body-secondary`.
|
|
84
|
+
- Treat `text-*-emphasis` as adaptive but optional. Use it only for a deliberate semantic foreground
|
|
85
|
+
on a known, measured surface, not merely because that surface has a subtle fill.
|
|
86
|
+
- Reserve `text-bg-*` for a deliberate solid pair. Bootstrap selects its foreground with Sass at
|
|
87
|
+
build time, not through runtime contrast calculation. Recheck after theme-variable changes;
|
|
88
|
+
see [Color and background](https://getbootstrap.com/docs/5.3/helpers/color-background/).
|
|
89
|
+
- Do not invent `text-bg-*-subtle`; stock Bootstrap does not ship that helper.
|
|
90
|
+
|
|
91
|
+
## Preserve the cascade
|
|
92
|
+
|
|
93
|
+
Inspect the winning declaration before changing a color. Remove a conflicting utility or local
|
|
94
|
+
rule before adding specificity. A literal moved into an unchanging `--bs-*` variable remains an
|
|
95
|
+
unchanging color; the prefix does not prove adaptation.
|
|
96
|
+
|
|
97
|
+
Keep native component foregrounds and states. Do not apply `color: inherit` to all descendants or
|
|
98
|
+
strip every text utility: alerts, validation feedback, links, and selected controls own meaningful
|
|
99
|
+
foreground behavior. Override only the element that violates its surface contract.
|
|
100
|
+
|
|
101
|
+
Use `text-reset` only to restore inheritance where a component or utility has replaced it. The
|
|
102
|
+
helper sets `color: inherit`, not a chosen palette color. Use `text-body` only when the element
|
|
103
|
+
must establish the active mode's body foreground on an owned surface, not as a universal reset.
|
|
104
|
+
Neither helper repairs an inappropriate ancestor by itself.
|
|
105
|
+
|
|
106
|
+
Keep links on Bootstrap's link rules. For a deliberate high-contrast neutral link, use
|
|
107
|
+
`link-body-emphasis`; among stock 5.3 colored-link helpers, only that helper adapts to color modes.
|
|
108
|
+
Do not override a link with a text utility and lose its hover/focus treatment; see
|
|
109
|
+
[Colored links](https://getbootstrap.com/docs/5.3/helpers/colored-links/).
|
|
110
|
+
|
|
111
|
+
Use opacity utilities only where the painted rule consumes their variable. Stock `bg-*-subtle`
|
|
112
|
+
rules do not consume `--bs-bg-opacity`; adding `bg-opacity-*` does not tint them. Check the same
|
|
113
|
+
relationship for emphasis text and subtle borders. Do not use whole-element opacity to create a
|
|
114
|
+
quiet panel with information-bearing children.
|
|
115
|
+
|
|
116
|
+
## Scope the mode
|
|
117
|
+
|
|
118
|
+
Use the host's mode controller. With Bootstrap's attribute strategy, set the resolved `light` or
|
|
119
|
+
`dark` value on `<html>`; scope an intentional exception with `data-bs-theme` on its boundary.
|
|
120
|
+
Do not pin components to dark merely because the page happens to be dark during development.
|
|
121
|
+
|
|
122
|
+
On a generic nested region, establish its surface as well as its variables:
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<section data-bs-theme="dark" class="bg-body text-body p-3" aria-labelledby="preview-heading">
|
|
126
|
+
<h2 id="preview-heading" class="h6">Preview</h2>
|
|
127
|
+
<div class="bg-primary-subtle rounded p-3">This text inherits from the preview.</div>
|
|
128
|
+
</section>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Keep the body foreground at that owned boundary; add no text-color classes to its ordinary
|
|
132
|
+
children. A component that already consumes its mode's foreground and background, such as a
|
|
133
|
+
`.dropdown-menu`, can establish its own pair without these utilities.
|
|
134
|
+
|
|
135
|
+
Do not treat `data-bs-theme` as paint. Changing variables on a plain element does not recompute a
|
|
136
|
+
`color` already inherited from outside the scope. Check the boundary guidance in Bootstrap's
|
|
137
|
+
[5.3.0 color-mode notes](https://blog.getbootstrap.com/2023/05/30/bootstrap-5-3-0/).
|
|
138
|
+
|
|
139
|
+
Resolve a portal, teleport, or `container: 'body'` overlay at its actual DOM mount point. Carry an
|
|
140
|
+
intentional local mode to that mount point; do not assume the trigger's ancestry follows it.
|
|
141
|
+
|
|
142
|
+
Avoid mode-sensitive aliases declared only at the root, such as `--app-text: var(--bs-body-color)`,
|
|
143
|
+
then inherited into a different local mode. Consume the Bootstrap variable at the component, or
|
|
144
|
+
rebind the alias at every supported mode boundary. Custom properties resolve their references
|
|
145
|
+
before inheritance; see [CSS Custom Properties](https://www.w3.org/TR/css-variables-1/).
|
|
146
|
+
|
|
147
|
+
When implementing a picker, validate persisted values, tolerate unavailable storage, and resolve
|
|
148
|
+
`auto` through `prefers-color-scheme` before setting the attribute. Follow system changes only
|
|
149
|
+
while the preference is automatic. Apply the resolved mode before first paint, keep server/client
|
|
150
|
+
initial state consistent, and update the picker's accessible state. Do not write
|
|
151
|
+
`data-bs-theme="auto"` without an explicitly implemented custom mode. Take the integration details
|
|
152
|
+
from [Bootstrap color modes](https://getbootstrap.com/docs/5.3/customize/color-modes/).
|
|
153
|
+
|
|
154
|
+
## Respect component ownership
|
|
155
|
+
|
|
156
|
+
### Badges and removable tags
|
|
157
|
+
|
|
158
|
+
For quiet status, prefer the utility-composed span in [Choose the surface](#choose-the-surface).
|
|
159
|
+
When preserving `.badge`, restore inheritance explicitly:
|
|
160
|
+
|
|
161
|
+
```html
|
|
162
|
+
<span class="badge bg-success-subtle text-reset">Paid</span>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Do not use `.badge bg-success-subtle` alone: stock `.badge` supplies a white foreground, not
|
|
166
|
+
inherited body text. Do not mistake the absence of a `text-*` class for the absence of a color
|
|
167
|
+
rule. Confirm the skin's badge rule; see [Badges](https://getbootstrap.com/docs/5.3/components/badge/).
|
|
168
|
+
Keep a removable tag's close button in the same mode and measure its hit area; a badge's small
|
|
169
|
+
font must not shrink the control below the package target floor.
|
|
170
|
+
|
|
171
|
+
### Alerts, buttons, and selection
|
|
172
|
+
|
|
173
|
+
Leave `.alert-*` on its native foreground, subtle background, border, and `.alert-link` treatment.
|
|
174
|
+
Do not add `text-reset` to an alert merely to enforce inheritance. Choose its announcement role
|
|
175
|
+
by urgency, not by the color or visual component.
|
|
176
|
+
|
|
177
|
+
Choose button rank before color. Keep `.btn-*` state rules; do not add `bg-*-subtle` to a button
|
|
178
|
+
and override its hover/active backgrounds with a utility's `!important`. For a custom variant,
|
|
179
|
+
map the full state contract through component variables and test it. Do not assume an outline
|
|
180
|
+
variant is safe or that a solid variant automatically passes.
|
|
181
|
+
|
|
182
|
+
Within an active row, tab, or filter, let ordinary labels and glyphs follow its tested foreground.
|
|
183
|
+
Remove a competing status tint before changing the selected fill. Keep a genuinely independent
|
|
184
|
+
nested badge on its own measured surface, or remove its fill and restore inheritance.
|
|
185
|
+
|
|
186
|
+
### Tables and overlays
|
|
187
|
+
|
|
188
|
+
Prefer the uncolored `.table` for automatic light/dark behavior. Treat `.table-primary` and the
|
|
189
|
+
other `.table-*` color variants as non-adaptive in stock 5.3 even though they expose CSS variables.
|
|
190
|
+
Do not describe their Sass-generated values as runtime color-mode mappings.
|
|
191
|
+
|
|
192
|
+
Inspect cells, not only the table or row. The base `--bs-table-bg` uses the body background; the
|
|
193
|
+
transparent default belongs to `--bs-table-accent-bg`. Striping, hover, and active states paint
|
|
194
|
+
cell overlays. Use the table's component variables for a required custom treatment rather than
|
|
195
|
+
stacking generic background utilities on a row; see
|
|
196
|
+
[Tables](https://getbootstrap.com/docs/5.3/content/tables/).
|
|
197
|
+
|
|
198
|
+
Let neutral cards, dropdowns, modals, offcanvas panels, and toasts retain their component-owned
|
|
199
|
+
surfaces. For an intentional local dark region, use `data-bs-theme` rather than the deprecated
|
|
200
|
+
`navbar-dark`, `dropdown-menu-dark`, `btn-close-white`, or `carousel-dark` classes. Check close
|
|
201
|
+
icons and overlay content after every supported mode transition.
|
|
202
|
+
|
|
203
|
+
## Extend the theme
|
|
204
|
+
|
|
205
|
+
Reuse the installed theme before introducing a palette. Keep primitives in the token source and
|
|
206
|
+
map only the required semantics and component states. Define light and dark as deliberate
|
|
207
|
+
hierarchies; do not mechanically invert every shade or increase decoration in dark mode.
|
|
208
|
+
|
|
209
|
+
Keep RGB companions aligned when a consumer reads them. Changing `--bs-primary` alone does not
|
|
210
|
+
update a utility reading `--bs-primary-rgb`, rebuild `.btn-primary`, or recompute a `text-bg-*`
|
|
211
|
+
foreground. Use the actual consumer's extension point and inspect the emitted rule.
|
|
212
|
+
|
|
213
|
+
Stock ramps are mechanical: `$blue-100…400` are `tint-color` mixes with white and `$blue-600…900`
|
|
214
|
+
are `shade-color` mixes with black, and the `-text-emphasis` / `-bg-subtle` / `-border-subtle`
|
|
215
|
+
triads are the same mixes. Hue stays fixed and saturation can only fall, so any brand base short
|
|
216
|
+
of full saturation washes out at the light end and goes muddy at the dark end; stock blue survives
|
|
217
|
+
only because its base is 98 % saturated. For a brand color, override the nine `$brand-100…900`
|
|
218
|
+
variables and the six triad variables (`$brand-text-emphasis`, `-bg-subtle`, `-border-subtle`,
|
|
219
|
+
each with its `-dark` twin) with hand-picked values before `variables` is imported; every
|
|
220
|
+
`.alert-brand`, `bg-brand-subtle`, `text-brand-emphasis`, and `table-brand` then consumes them.
|
|
221
|
+
Stock greys sit at hue 210° with 7–17 % saturation — cool, matched to the stock blue. For a warm
|
|
222
|
+
brand, override `$gray-100…900` as a complete set of nine with one hue and temperature; never drop
|
|
223
|
+
one warm grey into the cool set. Take the picking method from
|
|
224
|
+
[frontend-design.md](frontend-design.md) → Color as a constrained system.
|
|
225
|
+
|
|
226
|
+
With Sass, complete the light and dark emphasis/subtle maps for an added theme color. Inspect the
|
|
227
|
+
utility-value maps and extend the generated utilities when the build requires it. A variable's
|
|
228
|
+
presence does not prove that its expected class exists. Follow
|
|
229
|
+
[Theming & design tokens](bootstrap-reference.md#theming--design-tokens) for import order and
|
|
230
|
+
extension points. Add no custom color mode without a brief that requires it.
|
|
231
|
+
|
|
232
|
+
## Verify the result
|
|
233
|
+
|
|
234
|
+
Cross theme changes with narrow/wide layout states from [responsive-layout.md](responsive-layout.md).
|
|
235
|
+
Check a light page with its local dark hero, an opened mobile drawer, and any root-mounted dialog.
|
|
236
|
+
Do not infer their foregrounds from a desktop capture or from the theme attribute alone.
|
|
237
|
+
|
|
238
|
+
Run [Color-mode inheritance](inspection.md#color-mode-inheritance) and the applicable contrast,
|
|
239
|
+
target, and rendered-review checks against the loaded Bootstrap build and skin. Exercise the
|
|
240
|
+
existing mounted UI through light, dark, and back, including supported local scopes and overlays.
|
|
241
|
+
Report actual coverage; do not claim a host application pass from documentation or a stock fixture.
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
### Content Components
|
|
24
24
|
|
|
25
|
-
- Typography: `.h1`–`.h6`, `.display-1`–`.display-6`, `.lead`, `.small`
|
|
25
|
+
- Typography: `.h1`–`.h6`, `.display-1`–`.display-6`, `.lead`, `.small` (sizes, weights, and the `.small` `em` trap: [utilities.md](utilities.md) → Text)
|
|
26
|
+
- Lists and quotes: `.list-unstyled`, `.list-inline`, `.blockquote`, `.blockquote-footer` — icon bullets and promoted quotes per [utilities.md](utilities.md) → Composition habits
|
|
26
27
|
- Images: `.img-fluid`, `.img-thumbnail`, `.figure`
|
|
27
28
|
- Tables: `.table` plus its `.table-*` tone classes — see [Tables](#tables)
|
|
28
29
|
- Figures: `.figure`, `.figure-img`, `.figure-caption`
|
|
@@ -41,6 +42,10 @@ Full form patterns and validation JS: [bootstrap-reference.md](bootstrap-referen
|
|
|
41
42
|
|
|
42
43
|
## Component Markup
|
|
43
44
|
|
|
45
|
+
Preserve the component's native foreground and state rules. For quiet custom surfaces, inherit text
|
|
46
|
+
and use adaptive fills; take exceptions from [color-modes.md](color-modes.md). Do not copy a solid
|
|
47
|
+
variant merely because it appears in this catalog.
|
|
48
|
+
|
|
44
49
|
### Accordion
|
|
45
50
|
|
|
46
51
|
```html
|
|
@@ -91,17 +96,17 @@ Modifier classes: `.accordion-flush` (edge-to-edge, no outer borders); omit `dat
|
|
|
91
96
|
### Alerts
|
|
92
97
|
|
|
93
98
|
```html
|
|
94
|
-
<div class="alert alert-primary" role="
|
|
95
|
-
<div class="alert alert-success" role="
|
|
99
|
+
<div class="alert alert-primary" role="status">Sync complete</div>
|
|
100
|
+
<div class="alert alert-success" role="status">Changes saved</div>
|
|
96
101
|
<div class="alert alert-danger" role="alert">Danger alert</div>
|
|
97
102
|
<div class="alert alert-warning" role="alert">Warning alert</div>
|
|
98
103
|
|
|
99
|
-
<div class="alert alert-primary d-flex align-items-center" role="
|
|
104
|
+
<div class="alert alert-primary d-flex align-items-center" role="status">
|
|
100
105
|
<svg class="bi flex-shrink-0 me-2" role="img" aria-label="Info:">...</svg>
|
|
101
106
|
<div>Alert with icon</div>
|
|
102
107
|
</div>
|
|
103
108
|
|
|
104
|
-
<div class="alert alert-success alert-dismissible fade show" role="
|
|
109
|
+
<div class="alert alert-success alert-dismissible fade show" role="status">
|
|
105
110
|
<h4 class="alert-heading">Well done!</h4>
|
|
106
111
|
<p>Content here.</p>
|
|
107
112
|
<hr />
|
|
@@ -110,12 +115,24 @@ Modifier classes: `.accordion-flush` (edge-to-edge, no outer borders); omit `dat
|
|
|
110
115
|
</div>
|
|
111
116
|
```
|
|
112
117
|
|
|
113
|
-
`role="
|
|
118
|
+
Choose the announcement by urgency: `role="status"` for routine asynchronous results, `role="alert"` for urgent failures. Do not make every warning assertive or infer urgency from `.alert` styling. A static advisory does not require a live region merely because it has alert chrome. Take channel selection from [bootstrap-reference.md](bootstrap-reference.md) → Feedback discipline.
|
|
119
|
+
|
|
120
|
+
Keep the native `.alert-*` foreground, subtle background, and `.alert-link` states. Do not add blanket `text-reset` or text-color utilities to alerts. Measure their children on the actual fill; see [color-modes.md](color-modes.md) → Alerts, buttons, and selection.
|
|
114
121
|
|
|
115
|
-
|
|
122
|
+
A side accent is an accessory, one per region: `alert alert-warning border-0 border-start border-4 border-warning`. Zero the alert's own border first — `border-4` alone widens all four sides — and check the fixed `border-warning` against the dark `bg-warning-subtle` ([utilities.md](utilities.md) → Borders).
|
|
116
123
|
|
|
117
124
|
### Badge
|
|
118
125
|
|
|
126
|
+
Start quiet status with inherited text on a subtle fill. Use a plain span to avoid the badge's
|
|
127
|
+
built-in white foreground; when retaining `.badge`, use `text-reset` to restore inheritance:
|
|
128
|
+
|
|
129
|
+
```html
|
|
130
|
+
<span class="d-inline-flex rounded-pill bg-success-subtle px-2 py-1 small fw-semibold">Paid</span>
|
|
131
|
+
<span class="badge bg-success-subtle text-reset">Paid</span>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Reserve the solid variants for intentional prominence or a counter with its own paired surface:
|
|
135
|
+
|
|
119
136
|
```html
|
|
120
137
|
<span class="badge text-bg-primary">Primary</span>
|
|
121
138
|
<span class="badge text-bg-secondary">Secondary</span>
|
|
@@ -139,13 +156,13 @@ An alert is a subtle fill — apply the subtle-fill degradation rule to everythi
|
|
|
139
156
|
</button>
|
|
140
157
|
```
|
|
141
158
|
|
|
142
|
-
|
|
159
|
+
For an intentional solid badge, use a measured `text-bg-*` pair rather than a solid background alone. Its foreground is selected at Sass build time, not recalculated on a runtime theme change. Never make color the only carrier of meaning; keep visible text or an accessible label.
|
|
143
160
|
|
|
144
161
|
**A badge is never a textless mark.** Stock Bootstrap ships `.badge:empty { display: none }`, so an empty `<span class="badge">` used as a status dot renders nothing at all — the surface silently loses the state it claimed to show, and source review never sees it. A textless status mark is an **icon glyph** (see [Icons](#icons) → Status glyph marks), not a stripped badge.
|
|
145
162
|
|
|
146
|
-
|
|
163
|
+
State a badge's intended fill and inspect the skin. For a quiet badge use `bg-*-subtle text-reset`; for an unfilled badge use `bg-transparent text-reset`. Verify the inherited foreground on that actual surface in light and dark. A fill-only utility does not remove `.badge`'s white text; see [color-modes.md](color-modes.md) → Badges and removable tags.
|
|
147
164
|
|
|
148
|
-
A badge reporting an in-flight request is a live region: `role="status"` on the badge (or on the small wrapper that holds it) announces the settled state politely without stealing focus. Reserve `role="alert"` for
|
|
165
|
+
A badge reporting an in-flight request is a live region: `role="status"` on the badge (or on the small wrapper that holds it) announces the settled state politely without stealing focus. Reserve `role="alert"` for urgent results ([Alerts](#alerts)).
|
|
149
166
|
|
|
150
167
|
### Breadcrumb
|
|
151
168
|
|
|
@@ -188,10 +205,16 @@ The current page is `aria-current="page"` and not a link. Use breadcrumbs only f
|
|
|
188
205
|
|
|
189
206
|
Icon-only buttons need `aria-label` and a ≥24×24 px target (WCAG 2.2) — `btn-sm` icon clusters in toolbars are the common violation; pad rather than shrink.
|
|
190
207
|
|
|
191
|
-
|
|
208
|
+
The three sizes scale padding faster than font — `btn-sm` 4/8 px at 14 px, `btn` 6/12 at 16 px, `btn-lg` 8/16 at 20 px — so a large button reads as larger, not zoomed. Use them as shipped; do not derive a fourth size with `em` padding. Weight is `$font-weight-normal`; `fw-semibold` on a button is a deliberate emphasis choice, not a default.
|
|
209
|
+
|
|
210
|
+
Choose action rank, then a variant whose rest, hover, focus, active/checked, and disabled treatment works on its actual surface ([SKILL.md](../SKILL.md) → Hierarchy & actions). Do not override native button states with background or text utilities.
|
|
192
211
|
|
|
193
212
|
### Button Group
|
|
194
213
|
|
|
214
|
+
Keep joined groups on one line only while their labels and targets fit. For narrow filters or
|
|
215
|
+
review controls, use a select or independently spaced wrapping buttons; `flex-wrap` alone does
|
|
216
|
+
not make joined corners and shared borders into a coherent multiline group.
|
|
217
|
+
|
|
195
218
|
```html
|
|
196
219
|
<div class="btn-group" role="group" aria-label="Basic example">
|
|
197
220
|
<button type="button" class="btn btn-primary">Left</button>
|
|
@@ -219,7 +242,7 @@ Choose the `btn-*` class by contrast rather than by taste ([SKILL.md](../SKILL.m
|
|
|
219
242
|
<img src="..." class="card-img-top" alt="..." />
|
|
220
243
|
<div class="card-body">
|
|
221
244
|
<h5 class="card-title">Title</h5>
|
|
222
|
-
<h6 class="card-subtitle mb-2
|
|
245
|
+
<h6 class="card-subtitle mb-2">Subtitle</h6>
|
|
223
246
|
<p class="card-text">Text content.</p>
|
|
224
247
|
<a href="#" class="card-link">Link</a>
|
|
225
248
|
<a href="#" class="btn btn-primary">Button</a>
|
|
@@ -227,15 +250,23 @@ Choose the `btn-*` class by contrast rather than by taste ([SKILL.md](../SKILL.m
|
|
|
227
250
|
<ul class="list-group list-group-flush">
|
|
228
251
|
<li class="list-group-item">Item</li>
|
|
229
252
|
</ul>
|
|
230
|
-
<div class="card-footer
|
|
253
|
+
<div class="card-footer">Footer</div>
|
|
231
254
|
</div>
|
|
232
255
|
|
|
233
|
-
<div class="card
|
|
234
|
-
<div class="card border-primary">
|
|
256
|
+
<div class="card bg-primary-subtle">Quiet tinted card</div>
|
|
257
|
+
<div class="card border-primary-subtle">Quiet bordered card</div>
|
|
258
|
+
<div class="card border-0 shadow-sm">
|
|
259
|
+
Borderless raised card — page surface must differ from the card's
|
|
260
|
+
</div>
|
|
261
|
+
<div class="card border-0 border-top border-4 border-primary">
|
|
262
|
+
Top accent — border-0 first, or border-4 widens every side
|
|
263
|
+
</div>
|
|
235
264
|
<div class="card-group">Card group</div>
|
|
236
265
|
<div class="row row-cols-1 row-cols-md-3 g-4">Card grid (with h-100 on cards)</div>
|
|
237
266
|
```
|
|
238
267
|
|
|
268
|
+
Use `card` only where a group earns containment; try spacing and a surface change first. Card headers and footers are a 3 % tint of the body color, so `border-0` on `card-header` often reads cleaner than the shipped rule. One accent per region ([utilities.md](utilities.md) → Borders).
|
|
269
|
+
|
|
239
270
|
### Carousel
|
|
240
271
|
|
|
241
272
|
```html
|
|
@@ -356,6 +387,8 @@ Multiple targets: give each panel `.multi-collapse` and point separate triggers
|
|
|
356
387
|
|
|
357
388
|
`.dropdown-menu-dark` is deprecated — use `data-bs-theme="dark"` on the menu or an ancestor. Dropdowns have full keyboard support (arrows, Esc) built in. A dropdown is a **command menu** — for choosing a form value use `.form-select`, never a styled dropdown pretending to be an input.
|
|
358
389
|
|
|
390
|
+
A menu is a floating surface, not only a list of links: give it `dropdown-header` sections, a `dropdown-divider`, an icon, and a `small text-body-secondary` line under a `fw-semibold` label inside each `dropdown-item`, or a `row` of columns in a `p-3` menu, while keeping `dropdown-item` semantics on every choice.
|
|
391
|
+
|
|
359
392
|
### List Group
|
|
360
393
|
|
|
361
394
|
```html
|
|
@@ -404,6 +437,10 @@ Multiple targets: give each panel `.multi-collapse` and point separate triggers
|
|
|
404
437
|
|
|
405
438
|
### Modal
|
|
406
439
|
|
|
440
|
+
Keep width bounded and all actions vertically reachable on short viewports and enlarged text.
|
|
441
|
+
Use `modal-fullscreen-*-down` only with Bootstrap modal markup; a native `<dialog>` needs its own
|
|
442
|
+
measured sizing contract. Keep row-action dialogs outside table overflow ancestors.
|
|
443
|
+
|
|
407
444
|
**Build a blocking dialog on the native `<dialog>`.** `showModal()` brings focus containment, Esc, an inert background, and top-layer stacking from the platform — nothing to construct, nothing to dispose when the view unmounts, and no JS instance for a virtual-DOM framework to fight with over the same nodes. Leave the element itself unpainted and put Bootstrap chrome inside it:
|
|
408
445
|
|
|
409
446
|
```html
|
|
@@ -504,7 +541,9 @@ Bootstrap's modal enforces focus, adds `role="dialog"`/`aria-modal="true"`, clos
|
|
|
504
541
|
<nav class="navbar bg-body-tertiary sticky-top">Sticky top</nav>
|
|
505
542
|
|
|
506
543
|
<!-- Dark navbar: .navbar-dark is DEPRECATED — scope the theme instead -->
|
|
507
|
-
<nav class="navbar bg-
|
|
544
|
+
<nav class="navbar bg-body-tertiary" data-bs-theme="dark">
|
|
545
|
+
<a class="navbar-brand" href="#">Dark-themed navbar</a>
|
|
546
|
+
</nav>
|
|
508
547
|
```
|
|
509
548
|
|
|
510
549
|
### Navs & Tabs
|
|
@@ -592,6 +631,10 @@ Real switchable tab panels (JS-driven — buttons, not scroll anchors):
|
|
|
592
631
|
|
|
593
632
|
### Offcanvas
|
|
594
633
|
|
|
634
|
+
Take narrow/inline thresholds, trigger parity, and open-resize-close tests from
|
|
635
|
+
[responsive-layout.md](responsive-layout.md#handle-navigation-and-overlays). Match trigger and panel
|
|
636
|
+
breakpoints; do not leave a hidden focus trap or scroll lock after expansion.
|
|
637
|
+
|
|
595
638
|
```html
|
|
596
639
|
<button
|
|
597
640
|
class="btn btn-primary"
|
|
@@ -629,6 +672,10 @@ Real switchable tab panels (JS-driven — buttons, not scroll anchors):
|
|
|
629
672
|
|
|
630
673
|
### Pagination
|
|
631
674
|
|
|
675
|
+
On narrow screens, retain the current page and previous/next controls; reduce numbered links
|
|
676
|
+
before shrinking targets. Keep pagination outside the table scroller and preserve page state
|
|
677
|
+
when the presentation changes.
|
|
678
|
+
|
|
632
679
|
```html
|
|
633
680
|
<nav aria-label="Search results pages">
|
|
634
681
|
<ul class="pagination">
|
|
@@ -807,11 +854,11 @@ Gotcha: the spied element must be a scroll container (height/overflow, or focusa
|
|
|
807
854
|
### Spinners
|
|
808
855
|
|
|
809
856
|
```html
|
|
810
|
-
<div class="spinner-border
|
|
857
|
+
<div class="spinner-border" role="status">
|
|
811
858
|
<span class="visually-hidden">Loading...</span>
|
|
812
859
|
</div>
|
|
813
860
|
|
|
814
|
-
<div class="spinner-grow
|
|
861
|
+
<div class="spinner-grow" role="status">
|
|
815
862
|
<span class="visually-hidden">Loading...</span>
|
|
816
863
|
</div>
|
|
817
864
|
|
|
@@ -841,14 +888,14 @@ Gotcha: the spied element must be a scroll container (height/overflow, or focusa
|
|
|
841
888
|
<tbody>
|
|
842
889
|
<tr>
|
|
843
890
|
<th scope="row">INV-1042</th>
|
|
844
|
-
<td><span class="badge
|
|
891
|
+
<td><span class="badge bg-success-subtle text-reset">Paid</span></td>
|
|
845
892
|
<td class="text-end">$1,280.00</td>
|
|
846
893
|
</tr>
|
|
847
894
|
</tbody>
|
|
848
895
|
</table>
|
|
849
896
|
```
|
|
850
897
|
|
|
851
|
-
|
|
898
|
+
Combine structural modifiers as needed; choose color variants separately:
|
|
852
899
|
|
|
853
900
|
```css
|
|
854
901
|
.table-sm /* half padding — dense screens */
|
|
@@ -863,8 +910,8 @@ Modifiers (combine freely):
|
|
|
863
910
|
```
|
|
864
911
|
|
|
865
912
|
- **Responsive:** wrap in `.table-responsive{-sm|-md|-lg|-xl|-xxl}` for horizontal scroll. Caveat: the wrapper clips overflowing content — dropdown menus inside a responsive table get cut off.
|
|
866
|
-
- **
|
|
867
|
-
- **Theming:**
|
|
913
|
+
- **Color modes:** let the uncolored `.table` follow the page. Use `data-bs-theme="dark"` only for an intentional local mode, not as a permanent setting on a table that must follow the toggle.
|
|
914
|
+
- **Theming:** treat `.table-*` color variants as non-adaptive in stock 5.3; their CSS variables contain Sass-generated colors. The base table background uses the body background; the transparent default belongs to `--bs-table-accent-bg`. Inspect painted cells and their state overlays; see [color-modes.md](color-modes.md) → Tables and overlays.
|
|
868
915
|
- **Sticky headers are NOT built in.** Bootstrap ships no sticky-header feature; the pattern needs a few lines of custom CSS. That, plus selection columns, `aria-sort` sorting, bulk-action bars, and responsive strategies: [bootstrap-reference.md](bootstrap-reference.md) → Dense data tables.
|
|
869
916
|
|
|
870
917
|
### Toasts
|
|
@@ -879,13 +926,12 @@ Modifiers (combine freely):
|
|
|
879
926
|
<div class="toast-body">Changes published.</div>
|
|
880
927
|
</div>
|
|
881
928
|
|
|
882
|
-
<div class="toast align-items-center
|
|
929
|
+
<div class="toast align-items-center bg-primary-subtle border-0" role="status" aria-live="polite">
|
|
883
930
|
<div class="d-flex">
|
|
884
931
|
<div class="toast-body">Color tone</div>
|
|
885
932
|
<button
|
|
886
933
|
type="button"
|
|
887
934
|
class="btn-close me-2 m-auto"
|
|
888
|
-
data-bs-theme="dark"
|
|
889
935
|
data-bs-dismiss="toast"
|
|
890
936
|
aria-label="Close"
|
|
891
937
|
></button>
|
|
@@ -960,15 +1006,11 @@ Bootstrap's core CSS ships **no icons**. The `.bi` SVGs in examples come from th
|
|
|
960
1006
|
The textless mark that survives both themes — dots, ticks, rings, pulses — is a glyph, not a badge ([Badge](#badge)). Inline SVG or icon font, the composition rules are the same:
|
|
961
1007
|
|
|
962
1008
|
```html
|
|
963
|
-
<span
|
|
964
|
-
|
|
965
|
-
role="img"
|
|
966
|
-
aria-label="Healthy"
|
|
967
|
-
></span>
|
|
968
|
-
<span class="bi bi-circle fs-6 lh-1 text-body-secondary" role="img" aria-label="Not started"></span>
|
|
1009
|
+
<span class="bi bi-circle-fill fs-6 lh-1" role="img" aria-label="Healthy"></span>
|
|
1010
|
+
<span class="bi bi-circle fs-6 lh-1" role="img" aria-label="Not started"></span>
|
|
969
1011
|
```
|
|
970
1012
|
|
|
971
|
-
- **
|
|
1013
|
+
- **Inherit the owning foreground.** Keep ordinary glyphs on body or component text, including selected fills. Add `text-*-emphasis` only for a deliberate semantic tint on a known, measured surface; never apply it to every mark on a subtle fill. Measure meaningful marks at **≥ 3:1** in light and dark. Take cascade exceptions from [color-modes.md](color-modes.md).
|
|
972
1014
|
- **Filled and hollow say different things** — done vs pending, live vs idle — so pair glyphs that share one advance width (a filled/hollow pair from the same icon family). Mixed widths make a column of marks jitter row to row.
|
|
973
1015
|
- **Size with `fs-*` _and_ `lh-1`.** A glyph inherits the row's line-height, so an `fs-*` bump without `lh-1` grows the line box and pushes the row taller than its neighbors.
|
|
974
1016
|
- Give the mark an accessible name (`role="img"` + `aria-label`, or a `.visually-hidden` word next to an `aria-hidden` glyph) — a mark whose only meaning is its color and shape is color-only status.
|
|
@@ -1002,12 +1044,17 @@ The textless mark that survives both themes — dots, ticks, rings, pulses — i
|
|
|
1002
1044
|
|
|
1003
1045
|
### Selection fills
|
|
1004
1046
|
|
|
1005
|
-
|
|
1047
|
+
Keep the component's selected foreground on ordinary labels and glyphs. Remove a competing
|
|
1048
|
+
semantic tint before changing its active fill; handle an independently filled badge through
|
|
1049
|
+
[color-modes.md](color-modes.md) → Alerts, buttons, and selection.
|
|
1006
1050
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1051
|
+
Verify that chosen and unchosen filters remain distinguishable in light and dark. Do not assume
|
|
1052
|
+
that a neutral outline always inverts meaning or that an accent hue repairs it. Preserve the
|
|
1053
|
+
checked/pressed state and add a visible non-color cue when the fill alone is ambiguous.
|
|
1009
1054
|
|
|
1010
|
-
|
|
1055
|
+
Use `aria-current` for current navigation, `aria-selected` for tabs, and native checked state for
|
|
1056
|
+
checkboxes/radios. Match the visual state to the applicable pattern; do not apply `aria-current`
|
|
1057
|
+
to every selection widget.
|
|
1011
1058
|
|
|
1012
1059
|
### Navigation & overlays
|
|
1013
1060
|
|
|
@@ -1017,5 +1064,5 @@ Exactly one item in a selection carries `aria-current` — the visual fill and t
|
|
|
1017
1064
|
|
|
1018
1065
|
### Theming
|
|
1019
1066
|
|
|
1020
|
-
-
|
|
1067
|
+
- Preserve native component colors and prefer adaptive quiet surfaces. Take ownership, solid exceptions, nested modes, and deprecated-class replacements from [color-modes.md](color-modes.md). Do not assume every component variable adapts.
|
|
1021
1068
|
- To restyle a component, override its `--bs-{component}-*` variables in your own scope instead of writing high-specificity rules — see [bootstrap-reference.md](bootstrap-reference.md) → Theming & design tokens.
|