@ponchia/ui 0.7.0 → 0.8.1
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/CHANGELOG.md +178 -0
- package/README.md +3 -3
- package/classes/classes.json +79 -7
- package/classes/index.d.ts +53 -1
- package/classes/index.js +60 -0
- package/classes/vscode.css-custom-data.json +24 -0
- package/css/app.css +14 -3
- package/css/disclosure.css +7 -7
- package/css/feedback.css +11 -8
- package/css/forms.css +3 -3
- package/css/navigation.css +1 -1
- package/css/overlay.css +19 -5
- package/css/primitives.css +101 -6
- package/css/site.css +11 -5
- package/css/skins.css +97 -3
- package/css/state.css +161 -0
- package/css/table.css +1 -1
- package/css/tokens.css +6 -0
- package/css/workbench.css +151 -0
- package/dist/bronto.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/disclosure.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/navigation.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report-kit.css +1 -1
- package/dist/css/site.css +1 -1
- package/dist/css/skins.css +1 -1
- package/dist/css/state.css +1 -1
- package/dist/css/table.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -1
- package/docs/adr/0001-color-system.md +32 -3
- package/docs/contrast.md +102 -18
- package/docs/migrations/0.7-to-0.8.md +216 -0
- package/docs/package-contract.md +1 -0
- package/docs/reference.md +52 -1
- package/docs/reporting.md +8 -8
- package/docs/stability.md +31 -2
- package/docs/state.md +51 -1
- package/docs/theming.md +18 -0
- package/docs/usage.md +62 -2
- package/docs/workbench.md +83 -4
- package/llms.txt +1 -1
- package/package.json +13 -12
- package/tokens/figma.variables.json +84 -0
- package/tokens/index.d.ts +2 -2
- package/tokens/index.js +23 -0
- package/tokens/index.json +12 -0
- package/tokens/resolved.json +6 -0
- package/tokens/skins.js +117 -7
- package/tokens/tokens.dtcg.json +7 -1
package/dist/css/workbench.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer bronto{.ui-inspector{background: var(--panel);border: 1px solid var(--line);border-radius: var(--radius-md);display: grid;gap: var(--space-sm);padding: var(--space-md)}.ui-inspector__head{align-items: baseline;border-block-end: 1px solid var(--line);display: flex;gap: var(--space-sm);justify-content: space-between;padding-block-end: var(--space-xs)}.ui-inspector__body{display: grid;gap: var(--space-2xs)}.ui-toolstrip{align-items: center;background: var(--panel-strong);border: 1px solid var(--line-strong);border-radius: var(--radius-md);display: flex;flex-wrap: wrap;gap: var(--space-xs);min-inline-size: 0;padding: 0.35rem}.ui-toolstrip--floating{box-shadow: var(--shadow-raised)}.ui-toolstrip--compact{gap: var(--space-2xs);padding: 0.25rem}.ui-toolstrip__brand{align-items: baseline;display: inline-flex;flex: 0 1 auto;gap: var(--space-xs);min-inline-size: 0;padding-inline: var(--space-xs)}.ui-toolstrip__brand strong{color: var(--text);font-size: var(--text-sm)}.ui-toolstrip__context{color: var(--text-dim);font-size: var(--text-xs);min-inline-size: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.ui-toolstrip__group,.ui-toolstrip__actions{align-items: center;display: inline-flex;flex-wrap: wrap;gap: var(--space-2xs)}.ui-toolstrip__group{background: var(--panel-soft);border: 1px solid var(--line);border-radius: var(--radius-md);padding: 0.16rem}.ui-toolstrip__search{flex: 1 1 14rem;min-inline-size: min(100%,11rem)}.ui-toolstrip__actions{margin-inline-start: auto}.ui-segmented-buttons{align-items: center;background: var(--panel-soft);border: 1px solid var(--line);border-radius: var(--radius-md);display: inline-flex;flex-wrap: wrap;gap: 0.16rem;padding: 0.16rem}.ui-segmented-buttons__button{background: transparent;border: 1px solid transparent;border-radius: var(--radius-sm);color: var(--text-soft);cursor: pointer;font-family: var(--mono);font-size: var(--text-xs);font-weight: 700;letter-spacing: var(--tracking-wide);line-height: 1;min-block-size: 1.9rem;padding: 0.48rem 0.7rem;text-transform: uppercase}.ui-segmented-buttons__button[aria-pressed='true'],.ui-segmented-buttons__button.is-active{background: var(--accent);border-color: var(--accent);color: var(--button-text)}.ui-segmented-buttons__button:disabled,.ui-segmented-buttons__button[aria-disabled='true']{cursor: not-allowed;opacity: 0.45}.ui-property{align-items: baseline;display: grid;gap: var(--space-sm);grid-template-columns: minmax(6rem,38%) 1fr}.ui-property__label{color: var(--text-dim);font-family: var(--mono);font-size: var(--text-2xs);letter-spacing: var(--tracking-wide);text-transform: uppercase}.ui-property__value{color: var(--text);font-size: var(--text-sm);min-inline-size: 0}.ui-selectionbar{align-items: center;background: var(--panel-strong);border: 1px solid var(--line-strong);border-radius: var(--radius-md);box-shadow: var(--shadow-raised);display: flex;flex-wrap: wrap;gap: var(--space-sm) var(--space-md);justify-content: space-between;padding: 0.5rem 0.85rem}.ui-selectionbar__count{color: var(--text);font-family: var(--mono);font-size: var(--text-sm)}.ui-selectionbar__actions{display: flex;flex-wrap: wrap;gap: var(--space-xs)}@media (hover: hover){.ui-segmented-buttons__button:hover:not(:disabled,[aria-disabled='true'],[aria-pressed='true'],.is-active){background: var(--panel);border-color: var(--line-strong);color: var(--text)}}.ui-splitter{--splitter-pos: 50%;--splitter-handle: 0.75rem;--splitter-pane-min: 0px;background: var(--panel);border: 1px solid var(--line);border-radius: var(--radius-md);display: grid;grid-template-columns: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr);min-block-size: 18rem;overflow: hidden}.ui-splitter--vertical{grid-template-columns: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr)}.ui-splitter--horizontal{grid-template-columns: 1fr;grid-template-rows: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr)}.ui-splitter__pane{min-block-size: 0;min-inline-size: 0;overflow: auto;padding: var(--space-md)}.ui-splitter__handle{align-self: stretch;background: var(--panel-strong);border-block: 0;border-inline: 1px solid var(--line);cursor: col-resize;display: grid;min-inline-size: var(--splitter-handle);place-items: center;touch-action: none}.ui-splitter__handle::before{background: var(--line-strong);border-radius: var(--radius-pill);block-size: 2.5rem;content: "";inline-size: 2px}.ui-splitter__handle:hover::before,.ui-splitter__handle.is-active::before,.ui-splitter__handle[aria-valuenow]:focus-visible::before{background: var(--accent)}.ui-splitter__handle:focus-visible{outline: 2px solid var(--focus-ring);outline-offset: -2px}.ui-splitter--horizontal .ui-splitter__handle{border-block: 1px solid var(--line);border-inline: 0;cursor: row-resize;min-block-size: var(--splitter-handle);min-inline-size: 0}.ui-splitter--horizontal .ui-splitter__handle::before{block-size: 2px;inline-size: 2.5rem}@media (forced-colors: active){.ui-segmented-buttons__button[aria-pressed='true'],.ui-segmented-buttons__button.is-active{background: Highlight;border-color: Highlight;color: HighlightText}.ui-splitter__handle{border-color: CanvasText}.ui-splitter__handle::before{background: CanvasText}}}
|
|
1
|
+
@layer bronto{.ui-inspector{background: var(--panel);border: 1px solid var(--line);border-radius: var(--radius-md);display: grid;gap: var(--space-sm);padding: var(--space-md)}.ui-inspector__head{align-items: baseline;border-block-end: 1px solid var(--line);display: flex;gap: var(--space-sm);justify-content: space-between;padding-block-end: var(--space-xs)}.ui-inspector__body{display: grid;gap: var(--space-2xs)}.ui-toolstrip{align-items: center;background: var(--panel-strong);border: 1px solid var(--line-strong);border-radius: var(--radius-md);display: flex;flex-wrap: wrap;gap: var(--space-xs);min-inline-size: 0;padding: 0.35rem}.ui-toolstrip--floating{box-shadow: var(--shadow-raised)}.ui-toolstrip--compact{gap: var(--space-2xs);padding: 0.25rem}.ui-toolstrip--pane{background: none;border: 0;border-block-end: 1px solid var(--line);border-radius: 0;flex-wrap: nowrap;gap: var(--space-2xs);overflow-x: auto;padding: 0.3rem var(--space-xs);scrollbar-width: thin}.ui-toolstrip__fill{flex: 1 1 auto;min-inline-size: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.ui-toolstrip__brand{align-items: baseline;display: inline-flex;flex: 0 1 auto;gap: var(--space-xs);min-inline-size: 0;padding-inline: var(--space-xs)}.ui-toolstrip__brand strong{color: var(--text);font-size: var(--text-sm)}.ui-toolstrip__context{color: var(--text-dim);font-size: var(--text-xs);min-inline-size: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.ui-toolstrip__group,.ui-toolstrip__actions{align-items: center;display: inline-flex;flex-wrap: wrap;gap: var(--space-2xs)}.ui-toolstrip__group{background: var(--panel-soft);border: 1px solid var(--line);border-radius: var(--radius-md);padding: 0.16rem}.ui-toolstrip__search{flex: 1 1 14rem;min-inline-size: min(100%,11rem)}.ui-toolstrip__actions{margin-inline-start: auto}.ui-segmented-buttons{align-items: center;background: var(--panel-soft);border: 1px solid var(--line);border-radius: var(--radius-md);display: inline-flex;flex-wrap: wrap;gap: 0.16rem;padding: 0.16rem}.ui-segmented-buttons__button{background: transparent;border: 1px solid transparent;border-radius: var(--radius-sm);color: var(--text-soft);cursor: pointer;font-family: var(--mono);font-size: var(--text-xs);font-weight: 700;letter-spacing: var(--tracking-wide);line-height: 1;min-block-size: 1.9rem;padding: 0.48rem 0.7rem;text-transform: uppercase}.ui-segmented-buttons__button[aria-pressed='true'],.ui-segmented-buttons__button.is-active{background: var(--accent);border-color: var(--accent);color: var(--button-text)}.ui-segmented-buttons__button:disabled,.ui-segmented-buttons__button[aria-disabled='true']{cursor: not-allowed;opacity: 0.45}.ui-property{align-items: baseline;display: grid;gap: var(--space-sm);grid-template-columns: minmax(6rem,38%) 1fr}.ui-property__label{color: var(--text-dim);font-family: var(--mono);font-size: var(--text-2xs);letter-spacing: var(--tracking-wide);text-transform: uppercase}.ui-property__value{color: var(--text);font-size: var(--text-sm);min-inline-size: 0}.ui-pane{background: var(--panel);border: 1px solid var(--line);border-radius: var(--radius-md);display: flex;flex-direction: column;min-block-size: 0;min-inline-size: 0;overflow: hidden}.ui-pane__head{align-items: center;background: var(--bg-elevated);border-block-end: 1px solid var(--line);cursor: grab;display: flex;flex: none;gap: var(--space-2xs);min-block-size: var(--pane-head,2.5rem);padding: var(--space-2xs) var(--space-xs)}.ui-pane__head:active{cursor: grabbing}.ui-pane__title{flex: 1 1 auto;font-size: var(--text-xs);min-inline-size: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.ui-pane__title-input{background: var(--bg-elevated);border: 1px solid var(--accent);border-radius: var(--radius-sm);color: inherit;font: inherit;letter-spacing: inherit;margin-block: -1px;max-inline-size: 100%;min-inline-size: 0;padding: 0 0.25rem}.ui-pane__actions{display: flex;flex: 0 1 auto;flex-wrap: nowrap;gap: var(--space-2xs);min-inline-size: 0;overflow-x: auto;scrollbar-width: thin}.ui-pane__actions:empty{display: none}.ui-pane__body{display: flex;flex: 1;flex-direction: column;min-block-size: 0;min-inline-size: 0;overflow: auto}.ui-selectionbar{align-items: center;background: var(--panel-strong);border: 1px solid var(--line-strong);border-radius: var(--radius-md);box-shadow: var(--shadow-raised);display: flex;flex-wrap: wrap;gap: var(--space-sm) var(--space-md);justify-content: space-between;padding: 0.5rem 0.85rem}.ui-selectionbar__count{color: var(--text);font-family: var(--mono);font-size: var(--text-sm)}.ui-selectionbar__actions{display: flex;flex-wrap: wrap;gap: var(--space-xs)}.ui-selectionbar--anchored,.ui-toolstrip--anchored{--anchor-offset: var(--space-sm);inset-inline-start: 50%;max-inline-size: calc(100% - 2 * var(--space-md));position: absolute;transform: translateX(-50%)}.ui-selectionbar--anchored,.ui-toolstrip--anchored,.ui-selectionbar--anchor-block-end,.ui-toolstrip--anchor-block-end{inset-block: auto max(var(--anchor-offset),var(--safe-area-bottom))}.ui-selectionbar--anchor-block-start,.ui-toolstrip--anchor-block-start{inset-block: max(var(--anchor-offset),var(--safe-area-top)) auto}@media (hover: hover){.ui-segmented-buttons__button:hover:not(:disabled,[aria-disabled='true'],[aria-pressed='true'],.is-active){background: var(--panel);border-color: var(--line-strong);color: var(--text)}}.ui-splitter{--splitter-pos: 50%;--splitter-handle: 0.75rem;--splitter-pane-min: 0px;background: var(--panel);border: 1px solid var(--line);border-radius: var(--radius-md);display: grid;grid-template-columns: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr);min-block-size: 18rem;overflow: hidden}.ui-splitter--vertical{grid-template-columns: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr)}.ui-splitter--horizontal{grid-template-columns: 1fr;grid-template-rows: minmax(var(--splitter-pane-min),var(--splitter-pos)) var(--splitter-handle) minmax(0,1fr)}.ui-splitter__pane{min-block-size: 0;min-inline-size: 0;overflow: auto;padding: var(--space-md)}.ui-splitter__handle{align-self: stretch;background: var(--panel-strong);border-block: 0;border-inline: 1px solid var(--line);cursor: col-resize;display: grid;min-inline-size: var(--splitter-handle);place-items: center;touch-action: none}.ui-splitter__handle::before{background: var(--line-strong);border-radius: var(--radius-pill);block-size: 2.5rem;content: "";inline-size: 2px}.ui-splitter__handle:hover::before,.ui-splitter__handle.is-active::before,.ui-splitter__handle[aria-valuenow]:focus-visible::before{background: var(--accent)}.ui-splitter__handle:focus-visible{outline: 2px solid var(--focus-ring);outline-offset: -2px}.ui-splitter--horizontal .ui-splitter__handle{border-block: 1px solid var(--line);border-inline: 0;cursor: row-resize;min-block-size: var(--splitter-handle);min-inline-size: 0}.ui-splitter--horizontal .ui-splitter__handle::before{block-size: 2px;inline-size: 2.5rem}@media (forced-colors: active){.ui-segmented-buttons__button[aria-pressed='true'],.ui-segmented-buttons__button.is-active{background: Highlight;border-color: Highlight;color: HighlightText}.ui-splitter__handle{border-color: CanvasText}.ui-splitter__handle::before{background: CanvasText}}}
|
|
@@ -165,13 +165,42 @@ Hard acceptance criteria for every step below:
|
|
|
165
165
|
var(--accent) …)` declared on `:root` and only re-evaluates against the new
|
|
166
166
|
accent on the element that carries it; a skin on a subtree would leave that
|
|
167
167
|
family stale, so the selectors are `:root`-anchored and a subtree skin
|
|
168
|
-
no-ops. Each skin re-points
|
|
169
|
-
|
|
168
|
+
no-ops. Each skin re-points `--accent` (+ a dark `--dotmatrix-glow`); the
|
|
169
|
+
family + dot-matrix + glyphs follow automatically. Single-hue per skin →
|
|
170
170
|
keeps the one-accent discipline while unlocking range across skins. No
|
|
171
171
|
multi-hue palette. (A future per-subtree skin would need to re-declare the
|
|
172
172
|
derived family — deferred; whole-page is the natural colorway scope.) Skins
|
|
173
173
|
inherit the existing `forced-colors` + `print` behavior in `css/base.css` /
|
|
174
|
-
`css/forms.css
|
|
174
|
+
`css/forms.css`.
|
|
175
|
+
|
|
176
|
+
**Amended in 0.8.0 — a colorway also owns the neutral canvas.** The original
|
|
177
|
+
rule was accent-only, on the reasoning that the canvas is identity and the
|
|
178
|
+
accent is expression. A downstream consumer disproved it in the most direct
|
|
179
|
+
way available: offering these three as pickable looks, it found that
|
|
180
|
+
"Amber CRT" left the surface grey, and shipped a hand-written amber canvas of
|
|
181
|
+
its own — raw hex, dark theme only, outside OKLCH, outside `check-contrast`,
|
|
182
|
+
with `e-ink` silently un-tinted because a partial canvas has no failing edge.
|
|
183
|
+
Every one of those defects is a consequence of the rule, not of the consumer.
|
|
184
|
+
A look named after a phosphor display that renders on neutral grey is not a
|
|
185
|
+
colorway; it is an accent swatch with a colorway's name.
|
|
186
|
+
|
|
187
|
+
The amendment keeps the discipline that made the original rule right:
|
|
188
|
+
|
|
189
|
+
- The canvas is **derived, not picked**. Each of the ten neutrals
|
|
190
|
+
(`SKIN_CANVAS_TOKENS` in `tokens/skins.js`) keeps the core token's OKLCH
|
|
191
|
+
*lightness* exactly, adopts the skin accent's *hue*, and takes a small
|
|
192
|
+
role-scaled chroma. Contrast tracks relative luminance, which OKLCH L
|
|
193
|
+
tracks closely, so holding L fixed holds every pairing's ratio.
|
|
194
|
+
- It is **proven, not asserted**. `gen-contrast.mjs` widens a canvas-moving
|
|
195
|
+
skin's audit from the accent subset to the *full* 24-pair table, so all 21
|
|
196
|
+
gated pairings are re-measured per skin per theme on every run.
|
|
197
|
+
- The canvas is **all-or-nothing**, in both directions: `check-skins.mjs`
|
|
198
|
+
rejects a skin that re-points some neutrals but not others, and one that
|
|
199
|
+
re-points them in one theme but not the other. Those are exactly the two
|
|
200
|
+
shapes the consumer's hand-written version had.
|
|
201
|
+
- **Status colours stay locked.** They are not in `SKIN_CANVAS_TOKENS`: a
|
|
202
|
+
warning must look like a warning in every skin. Deriving status from a
|
|
203
|
+
colorway remains rejected (see Rejected alternatives).
|
|
175
204
|
5. **OKLCH for new work first.** *(done for colorways — accents authored in
|
|
176
205
|
OKLCH in `tokens/skins.js`; the contrast tooling now parses `oklch()` →
|
|
177
206
|
sRGB, so skin accents are gated, not eyeballed.)* The core ramp followed in
|
package/docs/contrast.md
CHANGED
|
@@ -111,36 +111,73 @@ palette untouched). Accents are authored in OKLCH; `--accent-text` is the
|
|
|
111
111
|
|
|
112
112
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
113
113
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
114
|
-
| `--
|
|
114
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.97:1 | Lc 99.0 | ✅ pass |
|
|
115
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.84:1 | Lc 105.8 | ✅ pass |
|
|
116
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.77:1 | Lc 94.4 | ✅ pass |
|
|
117
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.20:1 | Lc 91.3 | ✅ pass |
|
|
118
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.37:1 | Lc 98.1 | ✅ pass |
|
|
119
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.45:1 | Lc 86.8 | ✅ pass |
|
|
120
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.11:1 | Lc 71.4 | ✅ pass |
|
|
121
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.64:1 | Lc 78.2 | ✅ pass |
|
|
122
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.77:1 | Lc 66.9 | ✅ pass |
|
|
123
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.73:1 | Lc 78.7 | ✅ pass |
|
|
115
124
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 7.44:1 | Lc 85.6 | ✅ pass |
|
|
116
|
-
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 9.
|
|
125
|
+
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 9.19:1 | Lc 78.7 | ✅ pass |
|
|
117
126
|
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 6.48:1 | Lc 76.1 | ℹ️ not gated |
|
|
118
127
|
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 6.85:1 | Lc 79.9 | ℹ️ not gated |
|
|
119
128
|
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.66:1 | Lc 83.3 | ✅ pass |
|
|
120
129
|
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.66:1 | Lc 83.3 | ✅ pass |
|
|
121
|
-
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.
|
|
130
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.13:1 | Lc 71.2 | ✅ pass |
|
|
122
131
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.66:1 | Lc 78.0 | ✅ pass |
|
|
123
|
-
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.
|
|
132
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.13:1 | Lc 71.2 | ✅ pass |
|
|
133
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | Lc 74.6 | ✅ pass |
|
|
134
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | Lc 77.8 | ✅ pass |
|
|
135
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | Lc 78.9 | ✅ pass |
|
|
136
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | Lc 78.3 | ✅ pass |
|
|
137
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.41:1 | Lc 47.4 | ℹ️ not gated |
|
|
124
138
|
|
|
125
139
|
### Amber CRT — dark
|
|
126
140
|
|
|
127
141
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
128
142
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
143
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.01:1 | Lc 91.0 | ✅ pass |
|
|
144
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.64:1 | Lc 90.0 | ✅ pass |
|
|
145
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.43:1 | Lc 88.9 | ✅ pass |
|
|
146
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.19:1 | Lc 72.7 | ✅ pass |
|
|
147
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.18:1 | Lc 71.7 | ✅ pass |
|
|
148
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.27:1 | Lc 70.5 | ✅ pass |
|
|
149
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.16:1 | Lc 50.2 | ✅ pass |
|
|
150
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.51:1 | Lc 49.2 | ✅ pass |
|
|
151
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 5.93:1 | Lc 48.1 | ✅ pass |
|
|
129
152
|
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 11.84:1 | Lc 76.1 | ✅ pass |
|
|
130
153
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 10.77:1 | Lc 75.1 | ✅ pass |
|
|
131
|
-
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.
|
|
154
|
+
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.82:1 | Lc 65.4 | ✅ pass |
|
|
132
155
|
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.46:1 | Lc 20.8 | ℹ️ not gated |
|
|
133
156
|
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.51:1 | Lc 23.2 | ℹ️ not gated |
|
|
134
157
|
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 11.88:1 | Lc 71.6 | ✅ pass |
|
|
135
158
|
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 11.88:1 | Lc 71.6 | ✅ pass |
|
|
136
|
-
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.60:1 | Lc 69.
|
|
159
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.60:1 | Lc 69.8 | ✅ pass |
|
|
137
160
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 9.64:1 | Lc 68.9 | ✅ pass |
|
|
138
|
-
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.60:1 | Lc 69.
|
|
161
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.60:1 | Lc 69.8 | ✅ pass |
|
|
162
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 7.58:1 | Lc 56.6 | ✅ pass |
|
|
163
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 9.29:1 | Lc 66.6 | ✅ pass |
|
|
164
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 5.23:1 | Lc 41.5 | ✅ pass |
|
|
165
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 7.33:1 | Lc 54.8 | ✅ pass |
|
|
166
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.28:1 | Lc 14.5 | ℹ️ not gated |
|
|
139
167
|
|
|
140
168
|
### E-ink — light
|
|
141
169
|
|
|
142
170
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
143
171
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
172
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.98:1 | Lc 99.2 | ✅ pass |
|
|
173
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.79:1 | Lc 105.8 | ✅ pass |
|
|
174
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.73:1 | Lc 94.5 | ✅ pass |
|
|
175
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.16:1 | Lc 91.4 | ✅ pass |
|
|
176
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.29:1 | Lc 98.0 | ✅ pass |
|
|
177
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.39:1 | Lc 86.7 | ✅ pass |
|
|
178
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.09:1 | Lc 71.4 | ✅ pass |
|
|
179
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.61:1 | Lc 78.0 | ✅ pass |
|
|
180
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.74:1 | Lc 66.7 | ✅ pass |
|
|
144
181
|
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.23:1 | Lc 93.3 | ✅ pass |
|
|
145
182
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 13.47:1 | Lc 99.9 | ✅ pass |
|
|
146
183
|
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 8.78:1 | Lc 76.3 | ✅ pass |
|
|
@@ -151,51 +188,98 @@ palette untouched). Accents are authored in OKLCH; `--accent-text` is the
|
|
|
151
188
|
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.66:1 | Lc 90.4 | ✅ pass |
|
|
152
189
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.74:1 | Lc 97.0 | ✅ pass |
|
|
153
190
|
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.66:1 | Lc 90.4 | ✅ pass |
|
|
191
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | Lc 74.6 | ✅ pass |
|
|
192
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | Lc 77.8 | ✅ pass |
|
|
193
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | Lc 78.9 | ✅ pass |
|
|
194
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | Lc 78.3 | ✅ pass |
|
|
195
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.39:1 | Lc 47.1 | ℹ️ not gated |
|
|
154
196
|
|
|
155
197
|
### E-ink — dark
|
|
156
198
|
|
|
157
199
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
158
200
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
201
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.02:1 | Lc 91.1 | ✅ pass |
|
|
202
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.66:1 | Lc 90.1 | ✅ pass |
|
|
203
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.45:1 | Lc 89.0 | ✅ pass |
|
|
204
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.20:1 | Lc 72.8 | ✅ pass |
|
|
205
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.19:1 | Lc 71.8 | ✅ pass |
|
|
206
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.29:1 | Lc 70.6 | ✅ pass |
|
|
207
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.17:1 | Lc 50.3 | ✅ pass |
|
|
208
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.52:1 | Lc 49.3 | ✅ pass |
|
|
209
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 5.94:1 | Lc 48.2 | ✅ pass |
|
|
159
210
|
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.72:1 | Lc 80.3 | ✅ pass |
|
|
160
211
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.57:1 | Lc 79.3 | ✅ pass |
|
|
161
|
-
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.
|
|
212
|
+
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.67:1 | Lc 65.0 | ✅ pass |
|
|
162
213
|
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.38:1 | Lc 18.0 | ℹ️ not gated |
|
|
163
214
|
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.42:1 | Lc 19.9 | ℹ️ not gated |
|
|
164
215
|
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 12.86:1 | Lc 75.6 | ✅ pass |
|
|
165
216
|
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 12.86:1 | Lc 75.6 | ✅ pass |
|
|
166
|
-
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 11.
|
|
217
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 11.47:1 | Lc 74.1 | ✅ pass |
|
|
167
218
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 10.44:1 | Lc 73.1 | ✅ pass |
|
|
168
|
-
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 11.
|
|
219
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 11.47:1 | Lc 74.1 | ✅ pass |
|
|
220
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 7.58:1 | Lc 56.6 | ✅ pass |
|
|
221
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 9.29:1 | Lc 66.6 | ✅ pass |
|
|
222
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 5.23:1 | Lc 41.5 | ✅ pass |
|
|
223
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 7.33:1 | Lc 54.8 | ✅ pass |
|
|
224
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.29:1 | Lc 14.6 | ℹ️ not gated |
|
|
169
225
|
|
|
170
226
|
### Phosphor Green — light
|
|
171
227
|
|
|
172
228
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
173
229
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
174
|
-
| `--
|
|
230
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 18.02:1 | Lc 99.5 | ✅ pass |
|
|
231
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.72:1 | Lc 105.8 | ✅ pass |
|
|
232
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.67:1 | Lc 94.4 | ✅ pass |
|
|
233
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.10:1 | Lc 91.5 | ✅ pass |
|
|
234
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.14:1 | Lc 97.7 | ✅ pass |
|
|
235
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.26:1 | Lc 86.4 | ✅ pass |
|
|
236
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.06:1 | Lc 71.4 | ✅ pass |
|
|
237
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.53:1 | Lc 77.7 | ✅ pass |
|
|
238
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.68:1 | Lc 66.3 | ✅ pass |
|
|
239
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.26:1 | Lc 77.1 | ✅ pass |
|
|
175
240
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.85:1 | Lc 83.3 | ✅ pass |
|
|
176
|
-
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 9.
|
|
241
|
+
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 9.05:1 | Lc 78.5 | ✅ pass |
|
|
177
242
|
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 5.98:1 | Lc 74.1 | ℹ️ not gated |
|
|
178
243
|
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 6.32:1 | Lc 77.7 | ℹ️ not gated |
|
|
179
244
|
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.19:1 | Lc 80.7 | ✅ pass |
|
|
180
245
|
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.19:1 | Lc 80.7 | ✅ pass |
|
|
181
|
-
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.
|
|
246
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.74:1 | Lc 69.1 | ✅ pass |
|
|
182
247
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.19:1 | Lc 75.3 | ✅ pass |
|
|
183
|
-
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.
|
|
248
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.74:1 | Lc 69.1 | ✅ pass |
|
|
249
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | Lc 74.6 | ✅ pass |
|
|
250
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | Lc 77.8 | ✅ pass |
|
|
251
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | Lc 78.9 | ✅ pass |
|
|
252
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | Lc 78.3 | ✅ pass |
|
|
253
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.35:1 | Lc 46.4 | ℹ️ not gated |
|
|
184
254
|
|
|
185
255
|
### Phosphor Green — dark
|
|
186
256
|
|
|
187
257
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
188
258
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
189
|
-
| `--
|
|
259
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.11:1 | Lc 91.8 | ✅ pass |
|
|
260
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.80:1 | Lc 90.8 | ✅ pass |
|
|
261
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.57:1 | Lc 89.6 | ✅ pass |
|
|
262
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.28:1 | Lc 73.3 | ✅ pass |
|
|
263
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.30:1 | Lc 72.4 | ✅ pass |
|
|
264
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.38:1 | Lc 71.2 | ✅ pass |
|
|
265
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.22:1 | Lc 50.8 | ✅ pass |
|
|
266
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.60:1 | Lc 49.8 | ✅ pass |
|
|
267
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 6.01:1 | Lc 48.7 | ✅ pass |
|
|
268
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 13.13:1 | Lc 82.8 | ✅ pass |
|
|
190
269
|
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.99:1 | Lc 81.8 | ✅ pass |
|
|
191
|
-
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.
|
|
270
|
+
| `--text-soft` | `--accent-soft` over `--surface-muted` | Neutral tag/badge text on an accent tint | AA text (4.5:1) | 6.74:1 | Lc 65.6 | ✅ pass |
|
|
192
271
|
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.33:1 | Lc 15.3 | ℹ️ not gated |
|
|
193
272
|
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.37:1 | Lc 17.3 | ℹ️ not gated |
|
|
194
273
|
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 13.75:1 | Lc 79.7 | ✅ pass |
|
|
195
274
|
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 13.75:1 | Lc 79.7 | ✅ pass |
|
|
196
|
-
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 12.
|
|
275
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 12.22:1 | Lc 78.5 | ✅ pass |
|
|
197
276
|
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.16:1 | Lc 77.5 | ✅ pass |
|
|
198
|
-
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 12.
|
|
277
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 12.22:1 | Lc 78.5 | ✅ pass |
|
|
278
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 7.58:1 | Lc 56.6 | ✅ pass |
|
|
279
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 9.29:1 | Lc 66.6 | ✅ pass |
|
|
280
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 5.23:1 | Lc 41.5 | ✅ pass |
|
|
281
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 7.33:1 | Lc 54.8 | ✅ pass |
|
|
282
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.33:1 | Lc 15.1 | ℹ️ not gated |
|
|
199
283
|
|
|
200
284
|
## Data-viz palette (advisory)
|
|
201
285
|
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Migrating 0.7 to 0.8
|
|
2
|
+
|
|
3
|
+
Machine-readable migration graph: [`MIGRATIONS.json`](../../MIGRATIONS.json) —
|
|
4
|
+
it has no entry for this pair, because nothing was renamed or removed. Every
|
|
5
|
+
class, token, attribute, and export valid in 0.7 is still valid.
|
|
6
|
+
|
|
7
|
+
0.8.0 comes from auditing one real consumer's stylesheet in full. It repairs an
|
|
8
|
+
accessibility floor, adds three surfaces that consumer had to hand-write, and
|
|
9
|
+
changes what a colorway does. Only the last of those needs a decision from you.
|
|
10
|
+
|
|
11
|
+
## 1. Decide what your skins should look like — the one breaking change
|
|
12
|
+
|
|
13
|
+
**Only affects you if you set `data-bronto-skin`.** If you don't, skip to §2.
|
|
14
|
+
|
|
15
|
+
Until 0.7, a colorway moved `--accent` and nothing else; the neutral canvas
|
|
16
|
+
stayed grey, and ADR-0001 step 4 said so. From 0.8 a colorway also re-points ten
|
|
17
|
+
canvas tokens per theme:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
--bg --bg-elevated --panel --panel-strong --panel-soft
|
|
21
|
+
--line --line-strong --text --text-soft --text-dim
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
So "Amber CRT" now actually renders amber. Nothing in your source changes and no
|
|
25
|
+
checker will flag anything — the break is purely visual, which is why it is
|
|
26
|
+
worth reading rather than discovering.
|
|
27
|
+
|
|
28
|
+
**Contrast is not a regression risk.** Each neutral keeps the core token's OKLCH
|
|
29
|
+
*lightness* exactly and moves only hue plus a small chroma, and `check-contrast`
|
|
30
|
+
re-measures all 21 gated pairings per skin per theme. Status colours
|
|
31
|
+
(`--success` / `--warning` / `--danger` / `--info`) are untouched by design: a
|
|
32
|
+
warning must look like a warning in every skin.
|
|
33
|
+
|
|
34
|
+
### If you already hand-wrote a canvas for a skin
|
|
35
|
+
|
|
36
|
+
Delete it. That workaround is what motivated this change, and a hand-rolled
|
|
37
|
+
version is almost certainly not contrast-gated, probably covers one theme, and
|
|
38
|
+
probably misses whichever skin nobody opened.
|
|
39
|
+
|
|
40
|
+
### If you want the 0.7 look back
|
|
41
|
+
|
|
42
|
+
Re-declare the ten tokens after the skin import. They are ordinary custom
|
|
43
|
+
properties on a `:root[data-bronto-skin=…]` selector inside `@layer bronto`, so
|
|
44
|
+
un-layered app CSS wins without a specificity fight:
|
|
45
|
+
|
|
46
|
+
```css
|
|
47
|
+
@import '@ponchia/ui';
|
|
48
|
+
@import '@ponchia/ui/css/skins.css';
|
|
49
|
+
|
|
50
|
+
/* Keep the neutral canvas grey under every colorway. */
|
|
51
|
+
:root[data-bronto-skin] {
|
|
52
|
+
--bg: #f4f4f2;
|
|
53
|
+
--bg-elevated: #fbfbfa;
|
|
54
|
+
--panel: #ffffff;
|
|
55
|
+
--panel-strong: #ffffff;
|
|
56
|
+
--panel-soft: #ececea;
|
|
57
|
+
--line: #d8d8d4;
|
|
58
|
+
--line-strong: #a8a8a2;
|
|
59
|
+
--text: #0a0a0a;
|
|
60
|
+
--text-soft: #353533;
|
|
61
|
+
--text-dim: #686863;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
(Those are the 0.7 light values; take the dark set from `tokens/resolved.json`
|
|
66
|
+
and repeat under `:root[data-theme='dark'][data-bronto-skin]`.)
|
|
67
|
+
|
|
68
|
+
## 2. Delete your tap-target workaround
|
|
69
|
+
|
|
70
|
+
The coarse-pointer floor was written as a bare `2.9rem`, and `css/base.css` sets
|
|
71
|
+
`html { font-size: 0.9375rem }` — so it resolved to **43.5px**, half a pixel
|
|
72
|
+
under the 44 that WCAG 2.5.5 and both platform HIGs require, and less than that
|
|
73
|
+
under any host with a smaller root. If you noticed and declared your own 44px
|
|
74
|
+
floor, you can now drop it:
|
|
75
|
+
|
|
76
|
+
```diff
|
|
77
|
+
-:root { --touch-target: 44px; }
|
|
78
|
+
-
|
|
79
|
+
-@media (pointer: coarse) {
|
|
80
|
+
- .my-control { min-block-size: var(--touch-target); }
|
|
81
|
+
-}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Bronto's controls float to `var(--tap-target)` — `max(44px, 2.9rem)` — on their
|
|
85
|
+
own. For your *own* controls, consume the token rather than a literal:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
@media (pointer: coarse) {
|
|
89
|
+
.my-control {
|
|
90
|
+
min-block-size: var(--tap-target); /* 44px floor, WCAG 2.5.5 */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`--tap-target-min` is the WCAG 2.5.8 AA 24px floor, for controls that only have
|
|
96
|
+
to clear the smaller bar. Both clamp in px on purpose: **keep the clamp if you
|
|
97
|
+
override them.** A bare rem is how a 44px floor quietly becomes 43.5px.
|
|
98
|
+
|
|
99
|
+
## 3. Delete your safe-area declarations
|
|
100
|
+
|
|
101
|
+
0.7 had no `env()` awareness at all. If you declared your own insets, drop them —
|
|
102
|
+
the same four names now ship:
|
|
103
|
+
|
|
104
|
+
```diff
|
|
105
|
+
-:root {
|
|
106
|
+
- --safe-area-top: env(safe-area-inset-top, 0px);
|
|
107
|
+
- --safe-area-bottom: env(safe-area-inset-bottom, 0px);
|
|
108
|
+
-}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Eight viewport-anchored surfaces now read them: the app rail and topbar, a
|
|
112
|
+
sticky site header, the skip link, both toast stacks, the drawer modal, and the
|
|
113
|
+
lightbox. Every rule uses `max(<authored>, var(--safe-area-*))`, so **desktop
|
|
114
|
+
rendering is unchanged**.
|
|
115
|
+
|
|
116
|
+
They are indirected through custom properties rather than calling `env()` at the
|
|
117
|
+
point of use, which matters twice: a desktop test runner cannot emulate `env()`
|
|
118
|
+
but can override a property, and a host running inside its own chrome (an
|
|
119
|
+
embedded webview, a kiosk frame) can declare the real insets. Follow the same
|
|
120
|
+
convention for your own floating chrome:
|
|
121
|
+
|
|
122
|
+
```css
|
|
123
|
+
.my-floating-bar {
|
|
124
|
+
inset-block-end: max(1rem, var(--safe-area-bottom));
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 4. Two new opt-in ergonomics
|
|
129
|
+
|
|
130
|
+
Neither is required; both replace a common workaround.
|
|
131
|
+
|
|
132
|
+
**`ui-button__label`** — an icon button can keep its words for the accessible
|
|
133
|
+
name and for text-based test selectors while giving back the pixels. One markup
|
|
134
|
+
shape serves both forms, and no `aria-label` can drift out of sync with the
|
|
135
|
+
visible wording:
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<button class="ui-button ui-button--icon">
|
|
139
|
+
<span class="ui-icon" style="--icon-mask: …"></span>
|
|
140
|
+
<span class="ui-button__label">Delete</span>
|
|
141
|
+
</button>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Drop `--icon` and the same markup renders glyph + word. The slot ellipsises
|
|
145
|
+
rather than wrapping, so a labelled button in a tight bar shrinks instead of
|
|
146
|
+
pushing its neighbours out.
|
|
147
|
+
|
|
148
|
+
**`ui-button--dense`** — for bars whose *height* is the constraint: a pane title
|
|
149
|
+
bar, a packed toolbar, a table row's actions. It lowers only the visual floor,
|
|
150
|
+
to `--tap-target-min`. The coarse-pointer block still floats it to the full
|
|
151
|
+
`--tap-target`, so a control you shrink for a mouse is never shrunk for a
|
|
152
|
+
finger. `ui.button({ size: 'dense' })` in the recipe API.
|
|
153
|
+
|
|
154
|
+
## 5. Retire your own severity vocabulary
|
|
155
|
+
|
|
156
|
+
Nothing forces this, but it is the reason most likely to have produced
|
|
157
|
+
divergent code. Bronto shipped the tones without the **scale**, so consumers
|
|
158
|
+
invented tier names — and inside one app they drift, because each surface was
|
|
159
|
+
written on a different day. If you have more than one, `css/state.css` now
|
|
160
|
+
publishes the canonical ladder:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
critical › error › warning › notice › ok (+ unknown, outside the order)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
import { severity, SEVERITY_LEVELS } from '@ponchia/ui/classes';
|
|
168
|
+
|
|
169
|
+
severity('critical'); // { class: 'ui-severity', 'data-level': 'critical' }
|
|
170
|
+
severity('warning', { part: 'row' }); // { class: 'ui-severity-row', … }
|
|
171
|
+
SEVERITY_LEVELS; // sort and filter from this, not a local copy
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The level travels on `data-level` — one attribute name — so a chip, a row, a
|
|
175
|
+
dot, and your own element all read the same selector, and your own element can
|
|
176
|
+
take `var(--severity-tone)` without copying a colour table.
|
|
177
|
+
|
|
178
|
+
Map your existing tiers onto it rather than keeping both. `unknown` is the
|
|
179
|
+
landing spot for anything unmeasured or stale; do **not** map it to `ok`, which
|
|
180
|
+
is an assertion of health and is how a dead collector reads as a healthy system.
|
|
181
|
+
|
|
182
|
+
## 6. Other surfaces you may be hand-rolling
|
|
183
|
+
|
|
184
|
+
Each of these replaced something a real consumer had built locally. None is
|
|
185
|
+
required.
|
|
186
|
+
|
|
187
|
+
- **`.ui-pane`** — a grab header, an in-place rename input, and an actions slot
|
|
188
|
+
that scrolls rather than pushing its last control past the clipped edge. If
|
|
189
|
+
you have a node/window/panel with a draggable title bar, this is it.
|
|
190
|
+
`.ui-panel` is still just a padded card.
|
|
191
|
+
- **`.ui-toolstrip--pane`** — a control bar belonging to one pane rather than to
|
|
192
|
+
the app: no frame of its own, and it refuses to wrap so a second row cannot
|
|
193
|
+
resize live content underneath. Mark the shrinking element with
|
|
194
|
+
`.ui-toolstrip__fill`.
|
|
195
|
+
- **`.ui-selectionbar--anchored`** (and the same on `.ui-toolstrip`) — viewport
|
|
196
|
+
anchoring for a floating bar, safe-area aware. Use
|
|
197
|
+
`--anchor-block-start` for the bar that must *not* sit under the thumb.
|
|
198
|
+
- **`.ui-empty-state__glyph/__lead/__hint`** and **`--invite`** — the three
|
|
199
|
+
parts every empty surface re-invents, plus the distinction between reporting
|
|
200
|
+
absence and offering the next action.
|
|
201
|
+
|
|
202
|
+
## 7. If you read `tokens.dtcg.json`
|
|
203
|
+
|
|
204
|
+
Six new scale tokens are **deliberately absent** from it, listed in the root
|
|
205
|
+
extension's `omittedCssVariables`: the two tap-target floors are `max()`
|
|
206
|
+
comparisons and the four safe-area insets are `env()` reads, and neither has a
|
|
207
|
+
conforming DTCG shape. Emitting one arm of a clamp, or the 0px fallback of an
|
|
208
|
+
`env()`, would publish a value that is wrong everywhere it matters. Read
|
|
209
|
+
`tokens.json` for the authored CSS. This is the same treatment `--shadow` and
|
|
210
|
+
the em trackings already get.
|
|
211
|
+
|
|
212
|
+
## Nothing else changed
|
|
213
|
+
|
|
214
|
+
No class was renamed or removed. No export moved. `bronto-ui-check` will not
|
|
215
|
+
report anything new for a 0.7-clean consumer — which is worth stating plainly,
|
|
216
|
+
because the one breaking change in this release is invisible to it.
|
package/docs/package-contract.md
CHANGED
|
@@ -299,6 +299,7 @@ always includes `package.json`, `README.md`, `LICENSE`, and
|
|
|
299
299
|
| `docs/migrations/0.4-to-0.5.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
300
300
|
| `docs/migrations/0.5-to-0.6.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
301
301
|
| `docs/migrations/0.6-to-0.7.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
302
|
+
| `docs/migrations/0.7-to-0.8.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
302
303
|
| `docs/adr/0001-color-system.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
303
304
|
| `docs/adr/0002-scope-and-2026-baseline.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
304
305
|
| `docs/adr/0003-theme-model.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
package/docs/reference.md
CHANGED
|
@@ -9,7 +9,7 @@ rendering of every class is the kitchen-sink demo:
|
|
|
9
9
|
**<https://ponchia.github.io/bronto-ui/>**. Theming knobs and the token
|
|
10
10
|
contract: [docs/theming.md](theming.md).
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- 669 classes across 183 component groups
|
|
13
13
|
- Import the typed registry: `import { cls, ui, cx } from '@ponchia/ui/classes'`
|
|
14
14
|
- Validate markup as data (no JS/TS): `@ponchia/ui/classes.json` — the same
|
|
15
15
|
vocabulary as language-neutral JSON (`groups`, `classes`, `states`,
|
|
@@ -268,7 +268,9 @@ each one matches a real selector in the stylesheet.
|
|
|
268
268
|
| Registry key | Class | Kind |
|
|
269
269
|
| --- | --- | --- |
|
|
270
270
|
| `cls.button` | `ui-button` | base |
|
|
271
|
+
| `cls.buttonLabel` | `ui-button__label` | part |
|
|
271
272
|
| `cls.buttonDanger` | `ui-button--danger` | modifier |
|
|
273
|
+
| `cls.buttonDense` | `ui-button--dense` | modifier |
|
|
272
274
|
| `cls.buttonGhost` | `ui-button--ghost` | modifier |
|
|
273
275
|
| `cls.buttonIcon` | `ui-button--icon` | modifier |
|
|
274
276
|
| `cls.buttonLg` | `ui-button--lg` | modifier |
|
|
@@ -577,6 +579,10 @@ each one matches a real selector in the stylesheet.
|
|
|
577
579
|
| Registry key | Class | Kind |
|
|
578
580
|
| --- | --- | --- |
|
|
579
581
|
| `cls.emptyState` | `ui-empty-state` | base |
|
|
582
|
+
| `cls.emptyStateGlyph` | `ui-empty-state__glyph` | part |
|
|
583
|
+
| `cls.emptyStateHint` | `ui-empty-state__hint` | part |
|
|
584
|
+
| `cls.emptyStateLead` | `ui-empty-state__lead` | part |
|
|
585
|
+
| `cls.emptyStateInvite` | `ui-empty-state--invite` | modifier |
|
|
580
586
|
|
|
581
587
|
### `.ui-error-summary`
|
|
582
588
|
|
|
@@ -952,6 +958,17 @@ each one matches a real selector in the stylesheet.
|
|
|
952
958
|
| `cls.pagination` | `ui-pagination` | base |
|
|
953
959
|
| `cls.paginationItem` | `ui-pagination__item` | part |
|
|
954
960
|
|
|
961
|
+
### `.ui-pane`
|
|
962
|
+
|
|
963
|
+
| Registry key | Class | Kind |
|
|
964
|
+
| --- | --- | --- |
|
|
965
|
+
| `cls.pane` | `ui-pane` | base |
|
|
966
|
+
| `cls.paneActions` | `ui-pane__actions` | part |
|
|
967
|
+
| `cls.paneBody` | `ui-pane__body` | part |
|
|
968
|
+
| `cls.paneHead` | `ui-pane__head` | part |
|
|
969
|
+
| `cls.paneTitle` | `ui-pane__title` | part |
|
|
970
|
+
| `cls.paneTitleInput` | `ui-pane__title-input` | part |
|
|
971
|
+
|
|
955
972
|
### `.ui-panel`
|
|
956
973
|
|
|
957
974
|
| Registry key | Class | Kind |
|
|
@@ -1160,6 +1177,29 @@ each one matches a real selector in the stylesheet.
|
|
|
1160
1177
|
| `cls.selectionbar` | `ui-selectionbar` | base |
|
|
1161
1178
|
| `cls.selectionbarActions` | `ui-selectionbar__actions` | part |
|
|
1162
1179
|
| `cls.selectionbarCount` | `ui-selectionbar__count` | part |
|
|
1180
|
+
| `cls.selectionbarAnchorBlockEnd` | `ui-selectionbar--anchor-block-end` | modifier |
|
|
1181
|
+
| `cls.selectionbarAnchorBlockStart` | `ui-selectionbar--anchor-block-start` | modifier |
|
|
1182
|
+
| `cls.selectionbarAnchored` | `ui-selectionbar--anchored` | modifier |
|
|
1183
|
+
|
|
1184
|
+
### `.ui-severity`
|
|
1185
|
+
|
|
1186
|
+
| Registry key | Class | Kind |
|
|
1187
|
+
| --- | --- | --- |
|
|
1188
|
+
| `cls.severity` | `ui-severity` | base |
|
|
1189
|
+
|
|
1190
|
+
### `.ui-severity-dot`
|
|
1191
|
+
|
|
1192
|
+
| Registry key | Class | Kind |
|
|
1193
|
+
| --- | --- | --- |
|
|
1194
|
+
| `cls.severityDot` | `ui-severity-dot` | base |
|
|
1195
|
+
|
|
1196
|
+
### `.ui-severity-row`
|
|
1197
|
+
|
|
1198
|
+
| Registry key | Class | Kind |
|
|
1199
|
+
| --- | --- | --- |
|
|
1200
|
+
| `cls.severityRow` | `ui-severity-row` | base |
|
|
1201
|
+
| `cls.severityRowMeta` | `ui-severity-row__meta` | part |
|
|
1202
|
+
| `cls.severityRowTitle` | `ui-severity-row__title` | part |
|
|
1163
1203
|
|
|
1164
1204
|
### `.ui-shortcut`
|
|
1165
1205
|
|
|
@@ -1511,10 +1551,15 @@ each one matches a real selector in the stylesheet.
|
|
|
1511
1551
|
| `cls.toolstripActions` | `ui-toolstrip__actions` | part |
|
|
1512
1552
|
| `cls.toolstripBrand` | `ui-toolstrip__brand` | part |
|
|
1513
1553
|
| `cls.toolstripContext` | `ui-toolstrip__context` | part |
|
|
1554
|
+
| `cls.toolstripFill` | `ui-toolstrip__fill` | part |
|
|
1514
1555
|
| `cls.toolstripGroup` | `ui-toolstrip__group` | part |
|
|
1515
1556
|
| `cls.toolstripSearch` | `ui-toolstrip__search` | part |
|
|
1557
|
+
| `cls.toolstripAnchorBlockEnd` | `ui-toolstrip--anchor-block-end` | modifier |
|
|
1558
|
+
| `cls.toolstripAnchorBlockStart` | `ui-toolstrip--anchor-block-start` | modifier |
|
|
1559
|
+
| `cls.toolstripAnchored` | `ui-toolstrip--anchored` | modifier |
|
|
1516
1560
|
| `cls.toolstripCompact` | `ui-toolstrip--compact` | modifier |
|
|
1517
1561
|
| `cls.toolstripFloating` | `ui-toolstrip--floating` | modifier |
|
|
1562
|
+
| `cls.toolstripPane` | `ui-toolstrip--pane` | modifier |
|
|
1518
1563
|
|
|
1519
1564
|
### `.ui-tooltip`
|
|
1520
1565
|
|
|
@@ -1672,6 +1717,12 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
|
|
|
1672
1717
|
| `--space-lg` | `1.35rem` |
|
|
1673
1718
|
| `--space-xl` | `1.75rem` |
|
|
1674
1719
|
| `--space-2xl` | `2.5rem` |
|
|
1720
|
+
| `--tap-target` | `max(44px, 2.9rem)` |
|
|
1721
|
+
| `--tap-target-min` | `max(24px, 1.6rem)` |
|
|
1722
|
+
| `--safe-area-top` | `env(safe-area-inset-top, 0px)` |
|
|
1723
|
+
| `--safe-area-right` | `env(safe-area-inset-right, 0px)` |
|
|
1724
|
+
| `--safe-area-bottom` | `env(safe-area-inset-bottom, 0px)` |
|
|
1725
|
+
| `--safe-area-left` | `env(safe-area-inset-left, 0px)` |
|
|
1675
1726
|
| `--mono` | `'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'SF Mono', ui-monospace, monospace` |
|
|
1676
1727
|
| `--sans` | `'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif` |
|
|
1677
1728
|
| `--dot-font` | `'Doto', var(--mono)` |
|
package/docs/reporting.md
CHANGED
|
@@ -54,18 +54,18 @@ No install? Link the same files from a CDN. Pin the version — pre-1.0, breakin
|
|
|
54
54
|
changes ship in the minor (see [stability.md](./stability.md)):
|
|
55
55
|
|
|
56
56
|
```html
|
|
57
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
58
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
57
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/bronto.css" />
|
|
58
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/css/report-kit.css" />
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Leaf-by-leaf CDN imports use the same `dist/css/` paths:
|
|
62
62
|
|
|
63
63
|
```html
|
|
64
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
65
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
66
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
67
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
68
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
64
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/bronto.css" />
|
|
65
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/css/report.css" />
|
|
66
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/css/dataviz.css" />
|
|
67
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/css/annotations.css" />
|
|
68
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/css/legend.css" />
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
The CDN serves the package's own `fonts/` next to the CSS, so font URLs resolve
|
|
@@ -879,7 +879,7 @@ or validation runtime.
|
|
|
879
879
|
|
|
880
880
|
```json
|
|
881
881
|
{
|
|
882
|
-
"$schema": "https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
882
|
+
"$schema": "https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/schemas/report-claims.v1.schema.json",
|
|
883
883
|
"schemaVersion": "bronto-report-claims.v1",
|
|
884
884
|
"report": { "title": "Decision readiness", "type": "decision" },
|
|
885
885
|
"claims": [
|