@orkestrel/scaffold 0.0.58 → 0.0.60
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/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +91 -82
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +5 -5
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +10 -10
- package/dist/host/agents/skills/enterprise-bootstrap/references/inputs.md +501 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +167 -0
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +2 -2
- package/dist/host/agents/skills/orkestrel-polish-surface/SKILL.md +4 -1
- package/dist/host/agents/skills/orkestrel-polish-surface/references/capture-harness.md +71 -50
- package/dist/host/agents/skills/orkestrel-prove-journey/SKILL.md +93 -29
- package/dist/host/agents/skills/orkestrel-prove-journey/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-prove-journey/references/captures.md +62 -38
- package/dist/host/agents/skills/orkestrel-prove-journey/references/decide.md +68 -0
- package/dist/host/agents/skills/orkestrel-prove-journey/references/layer.md +107 -79
- package/dist/host/agents/skills/orkestrel-prove-journey/references/statechart.md +84 -0
- package/dist/host/agents/skills/orkestrel-prove-journey/references/styles.md +87 -0
- package/dist/host/claude/agents/orkestrel.md +11 -10
- package/dist/host/claude/skills/orkestrel-prove-journey/SKILL.md +1 -1
- package/dist/host/manifest.json +43 -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 +0 -0
- package/dist/src/core/index.cjs +5 -5
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +5 -5
- package/dist/src/core/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -24,18 +24,22 @@ every claim about the result from what renders.
|
|
|
24
24
|
Open the reference that owns a subject before writing markup. Never guess a class name: an invented
|
|
25
25
|
utility (`.vw-50`, `.pointer-events-none`) has no rule in the shipped CSS and fails silently. Pick
|
|
26
26
|
components from [components.md](references/components.md) → Choosing components, take their markup
|
|
27
|
-
from the same file, and take fine layout from [utilities.md](references/utilities.md).
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
from the same file, and take fine layout from [utilities.md](references/utilities.md). Pick an
|
|
28
|
+
input's affordance from [inputs.md](references/inputs.md) by what the person is asked for, not by
|
|
29
|
+
what a schema calls the field. Where Bootstrap ships no component for the need — combobox, date
|
|
30
|
+
picker, tags input, data grid, tree — work the native-first ladder in
|
|
31
|
+
[bootstrap-reference.md](references/bootstrap-reference.md) → When not to hand-roll before building
|
|
32
|
+
one.
|
|
31
33
|
|
|
32
34
|
| Layer | File | Holds |
|
|
33
35
|
| -------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
34
|
-
| Operate | `SKILL.md`
|
|
36
|
+
| Operate | `SKILL.md` | Process, decision rules, checklist |
|
|
35
37
|
| Design craft | [frontend-design.md](references/frontend-design.md) | Aesthetic, typography, signature, interface copy, anti-defaults |
|
|
36
38
|
| Components | [components.md](references/components.md) | Bootstrap component markup + enterprise selection notes |
|
|
39
|
+
| Inputs | [inputs.md](references/inputs.md) | Affordance per input category, its alternates, its rung, its states |
|
|
37
40
|
| Utilities | [utilities.md](references/utilities.md) | Class index, helpers, composition notes |
|
|
38
41
|
| Bootstrap deep | [bootstrap-reference.md](references/bootstrap-reference.md) | Color modes, theming/tokens, forms, JS lifecycle, a11y depth, enterprise patterns |
|
|
42
|
+
| Instruments | [inspection.md](references/inspection.md) | Property, population, reading, negative control, and coverage per instrument |
|
|
39
43
|
|
|
40
44
|
---
|
|
41
45
|
|
|
@@ -43,20 +47,20 @@ not to hand-roll before building one.
|
|
|
43
47
|
|
|
44
48
|
1. **Assume no stack.** Infer it from the workspace. Do not assume Vue, React, a skin library, a folder layout, or a named product.
|
|
45
49
|
2. **Target Bootstrap 5.3.x** class names and behaviors. Hold a compatible skin that keeps `.btn`, `.card`, `.form-control`, and `data-bs-*` to the same contracts.
|
|
46
|
-
3. **Follow the project's code law.**
|
|
50
|
+
3. **Follow the project's code law.** Take language, layout, and forbidden patterns from its `AGENTS.md` file, its lint rules, and its design system. Take UI craft and Bootstrap usage from here, and never language law.
|
|
47
51
|
4. **Write framework-neutral markup** — semantic HTML plus Bootstrap classes. Wire behavior with what the project already uses; in an SPA prefer the framework-native Bootstrap wrappers over raw `bootstrap.*` JS ([bootstrap-reference.md](references/bootstrap-reference.md) → JavaScript lifecycle).
|
|
48
52
|
5. **Keep this folder intact** so the relative links between its files resolve. Install or vendor it wherever the tooling looks for skills; the paths are tooling-specific, the content is not.
|
|
49
53
|
6. **Use the project's installed Bootstrap** when it has one; otherwise take the CDN snippet from [bootstrap-reference.md](references/bootstrap-reference.md) → Quick start (5.3.8).
|
|
50
|
-
7. **Apply this package** to UI, Bootstrap, and visual-design work matching the description
|
|
54
|
+
7. **Apply this package** to UI, Bootstrap, and visual-design work matching the frontmatter description. When the user points at it, treat it as authoritative for the visual pass.
|
|
51
55
|
|
|
52
56
|
---
|
|
53
57
|
|
|
54
58
|
## The mandate
|
|
55
59
|
|
|
56
60
|
1. **Design direction** — take a point of view rooted in the _subject_ (audience, job-to-be-done, vernacular). Take one justified aesthetic risk, in one place.
|
|
57
|
-
2. **Bootstrap execution** — components and utilities first
|
|
61
|
+
2. **Bootstrap execution** — take components and utilities first, custom CSS only when the system cannot express the need, and paint through `--bs-*` so light and dark both survive.
|
|
58
62
|
|
|
59
|
-
Match the density to the context: a marketing page
|
|
63
|
+
Match the density to the context: a marketing page can open with a thesis-hero, an authenticated
|
|
60
64
|
tool opens with clarity and scan paths. In product UI put the signature in the chrome, never in the
|
|
61
65
|
data ([frontend-design.md](references/frontend-design.md) → Where the signature lives).
|
|
62
66
|
|
|
@@ -64,9 +68,9 @@ data ([frontend-design.md](references/frontend-design.md) → Where the signatur
|
|
|
64
68
|
|
|
65
69
|
## Process
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
Read [frontend-design.md](references/frontend-design.md) before setting a direction; it owns subject
|
|
72
|
+
grounding, hero and thesis, typography, structure, motion, restraint, and interface copy. Then work
|
|
73
|
+
this loop:
|
|
70
74
|
|
|
71
75
|
1. **Ground** — name the subject, the audience, and the screen's single job, and state them. Use known user preferences and prior designs as hints, not templates.
|
|
72
76
|
2. **Plan** — build a token system: **color** (4–6 named values), **type** (display / body / utility), **layout** (prose plus ASCII if useful), **signature** (one memorable element).
|
|
@@ -74,53 +78,51 @@ setting a direction. The loop:
|
|
|
74
78
|
4. **Build** — compose Bootstrap components and utilities; map the plan's tokens onto theme variables or a thin skin, with no scattered one-off hex ([bootstrap-reference.md](references/bootstrap-reference.md) → Theming & design tokens). Watch selector specificity: a utility and a custom rule that cancel each other show up as padding and margin bugs.
|
|
75
79
|
5. **Critique the render** — remove one accessory. Check contrast, focus, `prefers-reduced-motion`, mobile, and every data state. Critique what rendered, not the markup.
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
([frontend-design.md](references/frontend-design.md) → Process).
|
|
81
|
+
Show a direction only after it satisfies the brief and the quality floor, and keep every earlier
|
|
82
|
+
draft private ([frontend-design.md](references/frontend-design.md) → Process).
|
|
79
83
|
|
|
80
84
|
**Rendered proof.** Settle every claim about a screen from a capture, never from source alone;
|
|
81
|
-
`.agents/orchestration.md` owns this law where it is present.
|
|
82
|
-
|
|
83
|
-
mechanism. For a full review-round campaign built on that evidence, use the
|
|
85
|
+
`.agents/orchestration.md` owns this law where it is present. Take captures at every viewport and
|
|
86
|
+
every theme the surface declares, plus an accessibility snapshot, as the review input, and use source only to corroborate
|
|
87
|
+
the mechanism. For a full review-round campaign built on that evidence, use the
|
|
84
88
|
`orkestrel-polish-surface` skill instead of improvising one here.
|
|
85
89
|
|
|
86
|
-
**Mechanical proof.**
|
|
87
|
-
control
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
**Mechanical proof.** Run every instrument in [inspection.md](references/inspection.md) with the
|
|
91
|
+
negative control it names, and treat an instrument whose negative control passes as broken;
|
|
92
|
+
`.claude/rules/quality.md` owns that law where it is present. Those instruments settle what a capture
|
|
93
|
+
cannot: composited contrast, authored classes against the shipped cascade, declared class
|
|
94
|
+
combinations, style escapes, token discipline, a custom rule doing a utility's job, and one glyph per
|
|
95
|
+
meaning. Hold every check the deliverable lists to that shape, whether or not inspection.md names
|
|
96
|
+
it: each states its population, its negative control, and its coverage, and a check that cannot
|
|
97
|
+
name a negative control is recorded as open rather than listed as a check.
|
|
93
98
|
|
|
94
99
|
---
|
|
95
100
|
|
|
96
101
|
## Bootstrap operating principles
|
|
97
102
|
|
|
98
|
-
1. **Mobile first** — smallest screen first, then `sm` / `md` / `lg` / `xl` / `xxl`.
|
|
99
|
-
2. **Semantic HTML** — `nav`, `main`, `section`, heading order.
|
|
100
|
-
3. **Work down the styling ladder
|
|
103
|
+
1. **Mobile first** — build the smallest screen first, then `sm` / `md` / `lg` / `xl` / `xxl`.
|
|
104
|
+
2. **Semantic HTML** — use `nav`, `main`, and `section`, and hold the heading order.
|
|
105
|
+
3. **Work down the styling ladder that follows** — component classes, then utilities, then Bootstrap's own extension points.
|
|
101
106
|
4. **Test every breakpoint you claim.**
|
|
102
107
|
5. **Reach for Bootstrap's own transitions before writing custom animation**, spend one orchestrated moment at most, and wrap any custom animation in `prefers-reduced-motion: no-preference` ([bootstrap-reference.md](references/bootstrap-reference.md) → Reduced motion).
|
|
103
|
-
6. **Resolve every treatment in the shipped cascade** — Bootstrap plus every skin and dependency stylesheet the page pulls in — never from docs memory. A class with no rule of its own
|
|
108
|
+
6. **Resolve every treatment in the shipped cascade** — Bootstrap plus every skin and dependency stylesheet the page pulls in — never from docs memory. A class with no rule of its own can still inherit one, and a token pair that passes in stock Bootstrap can fail under a compatible skin. Measure the `*-subtle` / `*-emphasis` recipes too, once per theme, with a reader that composites the translucent layers ([bootstrap-reference.md](references/bootstrap-reference.md) → Measuring the bars).
|
|
104
109
|
|
|
105
110
|
### The styling ladder
|
|
106
111
|
|
|
107
|
-
Work down these rungs in order. Reach a
|
|
108
|
-
the need.
|
|
112
|
+
Work down these rungs in order. Reach a rung only when the preceding one cannot express the need.
|
|
109
113
|
|
|
110
|
-
1. **The component's own classes, in its documented structure.** Use the right elements, nesting, class names, and required ARIA: a card is `.card` wrapping `.card-body` wrapping `.card-title`, not a `div` with borrowed padding.
|
|
114
|
+
1. **The component's own classes, in its documented structure.** Use the right elements, nesting, class names, and required ARIA: a card is `.card` wrapping `.card-body` wrapping `.card-title`, not a `div` with borrowed padding. Modifier classes, affordance states, color modes, and responsive behavior all hang off that structure.
|
|
111
115
|
2. **Bootstrap utilities, for refinement.** Spacing, flex, display, sizing, text, borders, color. Compose utilities rather than reaching past them, and use only classes that exist in [utilities.md](references/utilities.md).
|
|
112
116
|
3. **Bootstrap's own extension points.** Component `--bs-{component}-*` variables and the utilities API, when a real gap remains after the component-class and utility tiers.
|
|
113
|
-
4. **
|
|
117
|
+
4. **Leave anything beyond Bootstrap's conventions to the developer.** Stop at rung 3 and say plainly what rung 4 would require. Take rung 4 unasked only where [inspection.md](references/inspection.md) → When an authored rule is already earned opens it.
|
|
114
118
|
|
|
115
|
-
Never
|
|
119
|
+
Never reach first for any of these, because each ends the cascade for that element and then survives
|
|
120
|
+
no `--bs-*` retheming, no breakpoint change, and no color-mode change:
|
|
116
121
|
|
|
117
122
|
- a `style="..."` attribute;
|
|
118
123
|
- a `<style>` block in a page or component;
|
|
119
124
|
- a new stylesheet rule for something a utility already does.
|
|
120
125
|
|
|
121
|
-
Each ends the cascade for that element: it outranks the utilities, it ignores `--bs-*` retheming, and
|
|
122
|
-
it does not change across breakpoints or color modes.
|
|
123
|
-
|
|
124
126
|
### Hierarchy & actions
|
|
125
127
|
|
|
126
128
|
| Intent | Typical choice |
|
|
@@ -131,61 +133,67 @@ it does not change across breakpoints or color modes.
|
|
|
131
133
|
| Tertiary | `btn-link` or text links |
|
|
132
134
|
| Status | `badge` / `alert` / `*-emphasis` — **icon + color + word** |
|
|
133
135
|
|
|
134
|
-
**
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
consequence the solid variant. Solid variants paint their own background and measure identically on
|
|
139
|
-
every surface, and the stock fills sit at the 4.5:1 bar with nothing to spare. Re-measure a solid
|
|
140
|
-
variant whenever anything layers over it — an `opacity-*` utility, a translucent overlay, a skin's
|
|
141
|
-
own tint.
|
|
136
|
+
**Give any action that carries information or consequence a solid `btn-*` class, and keep outline
|
|
137
|
+
buttons decorative.** Against stock Bootstrap the whole `btn-outline-*` family misses 4.5:1 across
|
|
138
|
+
the dark theme and on light tinted surfaces — cards, subtle alerts — because an outline button
|
|
139
|
+
paints no background of its own and borrows the surface it sits on.
|
|
142
140
|
|
|
143
|
-
|
|
141
|
+
**Re-measure a solid fill whenever anything layers over it** — an `opacity-*` utility, a translucent
|
|
142
|
+
overlay, a skin's own tint — because the stock fills sit at the 4.5:1 bar with nothing to spare.
|
|
143
|
+
|
|
144
|
+
Draw a status mark with **no text** as an icon glyph, never as a `badge`
|
|
144
145
|
([components.md](references/components.md) → Badge).
|
|
145
146
|
|
|
146
147
|
### Surfaces, color, contrast
|
|
147
148
|
|
|
148
|
-
- **
|
|
149
|
-
- **
|
|
150
|
-
- `text-body-tertiary`
|
|
151
|
-
- **
|
|
152
|
-
- **
|
|
153
|
-
-
|
|
149
|
+
- **Measure these contrast bars in both themes:** **≥ 4.5:1** for anything information-bearing — `small`, captions, and meta text included — and **≥ 3:1** for textless marks, state indicators, and the hover/focus chrome that carries state. Verify Bootstrap's own palette too; the docs admit some defaults fall short. Read both themes — a pairing that passes light routinely fails dark.
|
|
150
|
+
- **Take the `-emphasis` pair for information-bearing status text.** Plain `text-success` and `text-danger` miss the bar across the dark theme and on light tinted surfaces, and `text-warning` is theme-asymmetric — unreadable on light, comfortable on dark. Never make a plain semantic color the encoding; use it only as decoration beside an encoding that already passes.
|
|
151
|
+
- **Tier text a person must read `text-body-secondary` or better**, and keep `text-body-tertiary` for decorative marks: tertiary measures under 4.5:1 on every surface in both themes, so it carries no information anywhere.
|
|
152
|
+
- **Inside `alert-*` and the `*-subtle` backgrounds, take `-emphasis` for information-bearing text and a solid `btn-*` class for every button.** A subtle fill degrades everything inside it one notch, so outline buttons and plain semantic text fail there even in light.
|
|
153
|
+
- **Carry no tone class inside a primary fill.** On `.active`, `.bg-primary`, and `text-bg-*` surfaces every tone class measured lands under the bar in both themes, the `-emphasis` family included, because the fill supplies its own contrast color and the tone class overrides it with one tuned for a different background. Let the surface's contrast color take the text, keep the status encoded by icon and word, and verify by capturing the selected state ([components.md](references/components.md) → Selection fills).
|
|
154
|
+
- Exempt a disabled control from the bars, but never leave a disabled **destructive** control at full danger saturation — at full strength it still reads as armed. Neutralize the danger tone while the control is disabled and carry the reason on the control with `aria-describedby` (plus `title` for pointer users), never `title` alone.
|
|
154
155
|
- Prefer `bg-body`, `bg-body-secondary`, `bg-body-tertiary` over raw `bg-white` / `bg-light`, and drive custom paint from `var(--bs-…)` — they track `data-bs-theme`, a hard-coded hex does not.
|
|
155
|
-
-
|
|
156
|
-
- On **dark surfaces**, scope `data-bs-theme="dark"` rather than the deprecated component
|
|
157
|
-
- Support `data-bs-theme="light"` and `dark` when the product offers both
|
|
156
|
+
- Take pairings from `text-bg-*`, `*-subtle`, `*-emphasis`, and `text-body` / `text-body-secondary`. `text-muted` is deprecated — use `text-body-secondary`.
|
|
157
|
+
- On **dark surfaces**, scope `data-bs-theme="dark"` rather than the deprecated `*-dark` component classes `navbar-dark`, `dropdown-menu-dark`, `btn-close-white`, and `carousel-dark`; gray-on-dark outlines often fail contrast.
|
|
158
|
+
- Support `data-bs-theme="light"` and `dark` when the product offers both, and take the mechanics from [bootstrap-reference.md](references/bootstrap-reference.md) → Color modes.
|
|
158
159
|
|
|
159
160
|
### Density, layout, responsive
|
|
160
161
|
|
|
161
|
-
-
|
|
162
|
+
- Take enterprise density from `table-sm`, `btn-sm` / `btn-group-sm`, and compact toolbars, but keep every interactive target **≥ 24×24px**, measured on the rendered box rather than assumed from the class (WCAG 2.2); pad hit areas rather than shrinking them.
|
|
162
163
|
- Where information density is the screen's job, take the `-sm` family across a control row together — `btn-sm` with `form-control-sm`, `form-select-sm`, `input-group-sm` — so the row shares one height. Never mix control sizes within one row.
|
|
163
|
-
-
|
|
164
|
+
- Take `.card` where grouping earns it; otherwise carry the grouping with spacing and type.
|
|
164
165
|
- Swap conditional chrome in place. A bulk-action bar or an alert that shoves the toolbar down shifts the layout mid-task.
|
|
165
|
-
-
|
|
166
|
+
- Take the app shell, dense tables, filter bars, and the ranked responsive strategies for wide data from [bootstrap-reference.md](references/bootstrap-reference.md) → Enterprise patterns, and spacing, toolbar, truncation, and print composition from [utilities.md](references/utilities.md) → Composition habits.
|
|
166
167
|
|
|
167
168
|
### States & feedback
|
|
168
169
|
|
|
169
|
-
- **
|
|
170
|
+
- **Ship every one of these states on every data surface:** ideal, empty, loading, partial, error. Treat the surface as unfinished until every one exists. Take loading thresholds, empty and error specifics, and the channel matrix for toast / inline alert / banner / modal from [bootstrap-reference.md](references/bootstrap-reference.md) → The data states, Feedback discipline.
|
|
170
171
|
- **Build a blocking decision on the native `<dialog>`.** `showModal()` brings focus containment, Esc, an inert background, and top-layer stacking from the platform, with no instance to construct and none to leak on unmount. Dress it with Bootstrap chrome inside ([components.md](references/components.md) → Modal). Reach for `.modal` and its JS only when the project already drives its dialogs that way.
|
|
171
|
-
- **
|
|
172
|
+
- **Make a destructive action undoable rather than interrupting**, and take the ladder and the confirmation contracts from [bootstrap-reference.md](references/bootstrap-reference.md) → Destructive actions.
|
|
172
173
|
|
|
173
174
|
### Forms
|
|
174
175
|
|
|
176
|
+
- Choose each field's affordance in [inputs.md](references/inputs.md) → The catalog by what the person is asked for, draw every state in that file's fixed set, and obey its cross-category rules — read-only chrome, the locked select, the chosen filter's accent tone, the non-drag path for a file drop.
|
|
175
177
|
- Give every field a visible label (top-aligned by default) or `.form-floating` — never placeholder-only.
|
|
176
178
|
- Validate on **blur**, re-validate error fields on input, re-check everything on submit, and keep submit **enabled**. Never disable submit as a validation strategy.
|
|
177
179
|
- Pair a focusable error summary with inline `.invalid-feedback` per field (`aria-describedby`, `aria-invalid`).
|
|
178
|
-
-
|
|
180
|
+
- Take layout, validation mechanics and their assistive-technology limitation, input groups, autosave, and multi-step rules from [bootstrap-reference.md](references/bootstrap-reference.md) → Forms in production, Wizards & multi-step forms.
|
|
179
181
|
|
|
180
182
|
### When custom CSS is justified
|
|
181
183
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
utilities, then the extension points
|
|
185
|
-
utilities API for missing utility steps
|
|
186
|
-
→ Theming).
|
|
184
|
+
Treat custom CSS as rung 4 and the developer's decision: propose it, name what it buys, and take it
|
|
185
|
+
unprompted only under the exception that follows. Exhaust rungs 1–3 first — correct component
|
|
186
|
+
structure, then utilities, then the extension points: component `--bs-{component}-*` variables for
|
|
187
|
+
restyling, the utilities API for missing utility steps
|
|
188
|
+
([bootstrap-reference.md](references/bootstrap-reference.md) → Theming).
|
|
189
|
+
|
|
190
|
+
Take an authored rule without asking only where an instrument in
|
|
191
|
+
[inspection.md](references/inspection.md) reports the vendor cascade failing a stated bar, the rule
|
|
192
|
+
cites that reading, the rule restores the bar and does nothing else, and the rule is written over
|
|
193
|
+
tokens. [inspection.md](references/inspection.md) → When an authored rule is already earned states
|
|
194
|
+
the whole condition. Treat anything wider as a proposal.
|
|
187
195
|
|
|
188
|
-
When the developer authorizes it:
|
|
196
|
+
When the developer authorizes it, or that exception opens:
|
|
189
197
|
|
|
190
198
|
- Name it in Bootstrap vocabulary.
|
|
191
199
|
- Take colors from `var(--bs-…)` and theme tokens so light and dark both work.
|
|
@@ -197,20 +205,20 @@ When the developer authorizes it:
|
|
|
197
205
|
|
|
198
206
|
## Accessibility baseline
|
|
199
207
|
|
|
200
|
-
-
|
|
201
|
-
- `aria-label
|
|
202
|
-
- `aria-current` / `aria-selected`
|
|
203
|
-
- `aria-expanded`
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
|
|
213
|
-
WCAG 2.2 deltas, APG pattern contracts, reduced motion, and SPA focus recipes
|
|
208
|
+
- Give the page a skip link to main, landmarks, and `h1` → `h2` heading order.
|
|
209
|
+
- Name every icon-only control with `aria-label`, and keep every target ≥ 24×24px.
|
|
210
|
+
- Mark active nav and tabs with `aria-current` / `aria-selected` — exactly one `aria-current` per selection.
|
|
211
|
+
- Wire every disclosure with `aria-expanded` and `aria-controls`.
|
|
212
|
+
- Wire help and errors with `aria-describedby`, and mark a failed field `aria-invalid`.
|
|
213
|
+
- Match the live region to the message: `role="status"` for an async status mark, `role="alert"` for an alert-styled notice.
|
|
214
|
+
- Associate a form with the name its host already gives the request (`aria-labelledby`) rather than repeating the prompt as its own label.
|
|
215
|
+
- Keep focus visible: keep the Bootstrap rings, use the `.focus-ring` helper for custom elements, and never write `outline: none`.
|
|
216
|
+
- Keep focus clear of sticky chrome (`scroll-margin-top`), and move focus deliberately on SPA route change, failed submit, and row delete.
|
|
217
|
+
- Never carry meaning by color alone, and verify the contrast.
|
|
218
|
+
- Give every drag interaction a non-drag alternative.
|
|
219
|
+
- Give every dialog `aria-labelledby`, let the platform or Bootstrap trap and restore focus rather than scripting it, and dispose Bootstrap instances in an SPA on unmount.
|
|
220
|
+
|
|
221
|
+
Take WCAG 2.2 deltas, APG pattern contracts, reduced motion, and SPA focus recipes from
|
|
214
222
|
[bootstrap-reference.md](references/bootstrap-reference.md) → Accessibility.
|
|
215
223
|
|
|
216
224
|
---
|
|
@@ -219,10 +227,12 @@ WCAG 2.2 deltas, APG pattern contracts, reduced motion, and SPA focus recipes:
|
|
|
219
227
|
|
|
220
228
|
```
|
|
221
229
|
Progress:
|
|
230
|
+
- [ ] Every check that follows, inspection.md instrument or not, reports its population, names the negative control that failed, and states its coverage; a check that can name no negative control is listed as open instead
|
|
222
231
|
- [ ] Project code law followed; no wrong-stack assumptions
|
|
223
232
|
- [ ] Subject, audience, single job stated
|
|
224
233
|
- [ ] Design plan critiqued against the AI defaults: palette, type, layout, one signature
|
|
225
234
|
- [ ] Shell from components.md, utilities from utilities.md; no invented class
|
|
235
|
+
- [ ] Input affordances from inputs.md; every state in its fixed set drawn, per field
|
|
226
236
|
- [ ] Styling ladder held: no `style` attribute, no `<style>` block, no custom rule doing a utility's job
|
|
227
237
|
- [ ] Plan tokens mapped to theme / --bs-* (no hex scatter); light and dark both shipped where both are offered
|
|
228
238
|
- [ ] Copy in user language, verbs consistent, empty/error/loading text useful
|
|
@@ -230,12 +240,11 @@ Progress:
|
|
|
230
240
|
- [ ] Contrast composited and measured in both themes: ≥ 4.5:1 information-bearing (small included), ≥ 3:1 marks and state chrome; meaning not color-alone
|
|
231
241
|
- [ ] Tiers held: `-emphasis` for information-bearing status, solid buttons for real actions, no tone class inside a filled surface
|
|
232
242
|
- [ ] Every treatment resolved in the shipped cascade, not from docs memory
|
|
233
|
-
- [ ] Authored classes checked against that cascade; one glyph per meaning; every instrument's control failed
|
|
234
243
|
- [ ] Keyboard: focus visible, not obscured, targets ≥ 24px, icon controls named
|
|
235
244
|
- [ ] Reduced motion respected; every drag has a non-drag path
|
|
236
245
|
- [ ] Forms: labels visible, blur validation, error summary + inline, submit enabled
|
|
237
246
|
- [ ] Claimed breakpoints spot-checked; RTL-safe (start/end only)
|
|
238
247
|
- [ ] States present: hover / focus / disabled / invalid / active
|
|
239
248
|
- [ ] SPA hygiene: JS instances disposed on unmount, or framework wrappers used
|
|
240
|
-
- [ ] Rendered proof: captures at
|
|
249
|
+
- [ ] Rendered proof: captures at every viewport and every theme the surface declares + an accessibility snapshot
|
|
241
250
|
```
|
|
@@ -81,7 +81,7 @@ CDN (5.3.8 is the current — and final — 5.3.x patch before 5.4):
|
|
|
81
81
|
|
|
82
82
|
## Color Modes (light / dark / custom)
|
|
83
83
|
|
|
84
|
-
The 5.3 color-mode system replaces the old per-component dark
|
|
84
|
+
The 5.3 color-mode system replaces the old per-component `*-dark` classes.
|
|
85
85
|
|
|
86
86
|
### Mechanics
|
|
87
87
|
|
|
@@ -290,7 +290,7 @@ Client-side, the documented pattern:
|
|
|
290
290
|
</div>
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
-
Details: input groups with feedback need `.has-validation` on the group (border-radius fix). `.valid
|
|
293
|
+
Details: input groups with feedback need `.has-validation` on the group (border-radius fix). `.valid-tooltip` and `.invalid-tooltip` need a `position-relative` parent. Validation colors are mode-adaptive via `--bs-form-valid-color`, `--bs-form-valid-border-color`, `--bs-form-invalid-color`, `--bs-form-invalid-border-color`.
|
|
294
294
|
|
|
295
295
|
### Autosave vs explicit save
|
|
296
296
|
|
|
@@ -354,7 +354,7 @@ Hold the baseline in [SKILL.md](../SKILL.md) → Accessibility baseline. Its Boo
|
|
|
354
354
|
- collects every painted layer from the element upward to the first opaque one, then composites them top over bottom (Porter-Duff `over`) onto that opaque base;
|
|
355
355
|
- composites a translucent foreground over that result before taking the ratio, rather than reading the declared color;
|
|
356
356
|
- measures both themes in one run, since the theme swap re-points the tokens under every layer;
|
|
357
|
-
- carries a negative control drawn from outside the population it covers — a pairing known to fail — and voids the run if that control passes.
|
|
357
|
+
- carries a negative control drawn from outside the population it covers — a pairing known to fail — and voids the run if that negative control passes.
|
|
358
358
|
|
|
359
359
|
Wire the reader into the suite once it has settled a question.
|
|
360
360
|
|
|
@@ -485,7 +485,7 @@ The Bootstrap implementation — a responsive offcanvas that renders inline abov
|
|
|
485
485
|
</div>
|
|
486
486
|
```
|
|
487
487
|
|
|
488
|
-
Give header cells an **opaque background** (`bg-body-secondary` or a table
|
|
488
|
+
Give header cells an **opaque background** (`bg-body-secondary` or a `.table-*` tone class) — table backgrounds are transparent by default, so rows show through a sticky header otherwise. Sticky chrome is the prime Focus-Not-Obscured offender: add `scroll-margin-top` on row focusables equal to the header height. Sticky first column only when row identity is lost on horizontal scroll — it costs paint and complexity.
|
|
489
489
|
|
|
490
490
|
- **Sorting:** the whole header is a button (not a bare caret), with a visible direction indicator, and `aria-sort="ascending|descending"` on the active `<th>` only:
|
|
491
491
|
|
|
@@ -551,7 +551,7 @@ Match friction to reversibility × blast radius:
|
|
|
551
551
|
|
|
552
552
|
Do not type-gate a single-row delete; do not one-tap a tenant wipe. Confirm only where this ladder calls for it — a confirmation on every action gets clicked through.
|
|
553
553
|
|
|
554
|
-
**Neutralize a disabled destructive control.** `btn-danger` at full saturation reads as armed whatever the `disabled` attribute says, and the contrast exemption for disabled controls does not excuse it. While the action is unavailable, drop to the neutral or outline
|
|
554
|
+
**Neutralize a disabled destructive control.** `btn-danger` at full saturation reads as armed whatever the `disabled` attribute says, and the contrast exemption for disabled controls does not excuse it. While the action is unavailable, drop to the neutral or outline `btn-*` class (or let the disabled state mute the fill) so the color stops promising an action, and say _why_ it is unavailable in text the assistive layer reaches: `aria-describedby` pointing at the reason, with `title` only as the pointer-user convenience on top. Never use `title` alone — it never reaches a keyboard or screen-reader user, and it disappears on touch.
|
|
555
555
|
|
|
556
556
|
## RTL
|
|
557
557
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
- Typography: `.h1`–`.h6`, `.display-1`–`.display-6`, `.lead`, `.small`
|
|
26
26
|
- Images: `.img-fluid`, `.img-thumbnail`, `.figure`
|
|
27
|
-
- Tables: `.table`
|
|
27
|
+
- Tables: `.table` plus its `.table-*` tone classes — see [Tables](#tables)
|
|
28
28
|
- Figures: `.figure`, `.figure-img`, `.figure-caption`
|
|
29
29
|
|
|
30
30
|
### Form Components
|
|
@@ -86,7 +86,7 @@ Full form patterns and validation JS: [bootstrap-reference.md](bootstrap-referen
|
|
|
86
86
|
</div>
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
Modifier classes: `.accordion-flush` (edge-to-edge, no outer borders); omit `data-bs-parent` to allow multiple items open.
|
|
90
90
|
|
|
91
91
|
### Alerts
|
|
92
92
|
|
|
@@ -188,7 +188,7 @@ The current page is `aria-current="page"` and not a link. Use breadcrumbs only f
|
|
|
188
188
|
|
|
189
189
|
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
190
|
|
|
191
|
-
Choose the
|
|
191
|
+
Choose the `btn-*` class by contrast rather than by taste ([SKILL.md](../SKILL.md) → Hierarchy & actions).
|
|
192
192
|
|
|
193
193
|
### Button Group
|
|
194
194
|
|
|
@@ -525,7 +525,7 @@ Bootstrap's modal enforces focus, adds `role="dialog"`/`aria-modal="true"`, clos
|
|
|
525
525
|
<ul class="nav nav-underline">
|
|
526
526
|
…
|
|
527
527
|
</ul>
|
|
528
|
-
<!-- 5.3: understated bottom-border
|
|
528
|
+
<!-- 5.3: understated bottom-border style -->
|
|
529
529
|
<ul class="nav nav-pills nav-fill">
|
|
530
530
|
…
|
|
531
531
|
</ul>
|
|
@@ -858,13 +858,13 @@ Modifiers (combine freely):
|
|
|
858
858
|
.table-active /* highlight a row/cell */
|
|
859
859
|
.table-group-divider /* thicker rule between <tbody> groups */
|
|
860
860
|
.caption-top /* caption above the table */
|
|
861
|
-
.table-primary … .table-dark /*
|
|
861
|
+
.table-primary … .table-dark /* tone classes, on table/tr/td */
|
|
862
862
|
.align-middle /* vertical alignment, on table/tr/td */
|
|
863
863
|
```
|
|
864
864
|
|
|
865
865
|
- **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
|
-
- **Dark tables:** `data-bs-theme="dark"` on the `<table>` (the `.table-dark`
|
|
867
|
-
- **Theming:**
|
|
866
|
+
- **Dark tables:** `data-bs-theme="dark"` on the `<table>` (the `.table-dark` class approach is superseded).
|
|
867
|
+
- **Theming:** the `.table-*` tone classes set CSS variables, not fixed colors — `--bs-table-bg`, `--bs-table-color`, `--bs-table-striped-bg`, `--bs-table-hover-bg`, `--bs-table-active-bg`, `--bs-table-border-color`. `--bs-table-bg` is transparent by default so striping/hover layer through.
|
|
868
868
|
- **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
869
|
|
|
870
870
|
### Toasts
|
|
@@ -881,7 +881,7 @@ Modifiers (combine freely):
|
|
|
881
881
|
|
|
882
882
|
<div class="toast align-items-center text-bg-primary border-0" role="status" aria-live="polite">
|
|
883
883
|
<div class="d-flex">
|
|
884
|
-
<div class="toast-body">Color
|
|
884
|
+
<div class="toast-body">Color tone</div>
|
|
885
885
|
<button
|
|
886
886
|
type="button"
|
|
887
887
|
class="btn-close me-2 m-auto"
|
|
@@ -1005,7 +1005,7 @@ The textless mark that survives both themes — dots, ticks, rings, pulses — i
|
|
|
1005
1005
|
A selected row, pill, or filter chip repaints everything inside it — marks included. These traps stay invisible until the selected state is captured in both themes:
|
|
1006
1006
|
|
|
1007
1007
|
- **A mark on an active fill of the same family disappears.** `.active` on a `list-group-item`, `nav-pill`, or `page-item` sets the item's own color, and a `text-bg-primary`-family mark inside it inherits or loses to that fill — present in the markup, gone on screen. Carry no tone class inside the fill ([SKILL.md](../SKILL.md) → Surfaces, color, contrast). Verify by capturing the selected row, not by reading the class list.
|
|
1008
|
-
- **`btn-check` filter labels invert in dark.** A `btn-outline-secondary` label reads as "chosen" in light and as "muted" in dark, because the checked fill and the surface swap relative weight. Give chosen filters an accent
|
|
1008
|
+
- **`btn-check` filter labels invert in dark.** A `btn-outline-secondary` label reads as "chosen" in light and as "muted" in dark, because the checked fill and the surface swap relative weight. Give chosen filters an accent tone class (a real theme color) rather than the neutral outline, so "chosen" reads the same way in both modes.
|
|
1009
1009
|
|
|
1010
1010
|
Exactly one item in a selection carries `aria-current` — the visual fill and the announced state must be the same item.
|
|
1011
1011
|
|
|
@@ -1017,5 +1017,5 @@ Exactly one item in a selection carries `aria-current` — the visual fill and t
|
|
|
1017
1017
|
|
|
1018
1018
|
### Theming
|
|
1019
1019
|
|
|
1020
|
-
- Components consume CSS variables — favor `text-bg-*`, `*-subtle`, and `data-bs-theme` over one-off colors; the deprecated `*-dark` component
|
|
1020
|
+
- Components consume CSS variables — favor `text-bg-*`, `*-subtle`, and `data-bs-theme` over one-off colors; the deprecated `*-dark` component classes (`navbar-dark`, `dropdown-menu-dark`, `btn-close-white`, `carousel-dark`) all map to `data-bs-theme="dark"`.
|
|
1021
1021
|
- 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.
|