@ponchia/ui 0.3.6 → 0.4.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +1063 -0
  2. package/README.md +31 -14
  3. package/behaviors/index.d.ts +3 -1
  4. package/behaviors/index.js +179 -106
  5. package/classes/index.d.ts +41 -0
  6. package/classes/index.js +42 -0
  7. package/classes/vscode.css-custom-data.json +18 -22
  8. package/css/dataviz.css +96 -0
  9. package/css/disclosure.css +29 -0
  10. package/css/dots.css +32 -2
  11. package/css/feedback.css +53 -0
  12. package/css/motion.css +88 -0
  13. package/css/overlay.css +52 -1
  14. package/css/report.css +382 -0
  15. package/css/skins.css +54 -0
  16. package/css/tokens.css +56 -32
  17. package/dist/bronto.css +1 -1
  18. package/dist/css/dataviz.css +1 -0
  19. package/dist/css/disclosure.css +1 -1
  20. package/dist/css/dots.css +1 -1
  21. package/dist/css/feedback.css +1 -1
  22. package/dist/css/motion.css +1 -1
  23. package/dist/css/overlay.css +1 -1
  24. package/dist/css/report.css +1 -0
  25. package/dist/css/skins.css +1 -0
  26. package/dist/css/tokens.css +1 -1
  27. package/docs/adr/0001-color-system.md +271 -0
  28. package/docs/adr/0002-scope-and-2026-baseline.md +104 -0
  29. package/docs/adr/0003-theme-model.md +94 -0
  30. package/docs/contrast.md +170 -51
  31. package/docs/reference.md +118 -19
  32. package/docs/reporting.md +270 -0
  33. package/docs/stability.md +37 -0
  34. package/docs/theming.md +84 -7
  35. package/docs/usage.md +67 -8
  36. package/glyphs/glyphs.d.ts +14 -1
  37. package/glyphs/glyphs.js +143 -2
  38. package/llms.txt +101 -5
  39. package/package.json +79 -5
  40. package/qwik/index.d.ts +55 -0
  41. package/qwik/index.js +129 -0
  42. package/react/index.d.ts +57 -0
  43. package/react/index.js +84 -0
  44. package/solid/index.d.ts +57 -0
  45. package/solid/index.js +85 -0
  46. package/tokens/charts.d.ts +37 -0
  47. package/tokens/charts.js +96 -0
  48. package/tokens/charts.json +61 -0
  49. package/tokens/index.d.ts +3 -3
  50. package/tokens/index.js +16 -18
  51. package/tokens/index.json +32 -36
  52. package/tokens/resolved.json +39 -41
  53. package/tokens/skins.d.ts +27 -0
  54. package/tokens/skins.js +62 -0
  55. package/tokens/tokens.dtcg.json +22 -34
package/docs/contrast.md CHANGED
@@ -38,63 +38,182 @@ Overall: **all contractual pairings meet their floor ✅**.
38
38
 
39
39
  ## Light theme
40
40
 
41
- | Foreground | Background | Role | Held to | Ratio | Verdict |
42
- | --- | --- | --- | --- | --- | --- |
43
- | `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.98:1 | ✅ pass |
44
- | `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.80:1 | ✅ pass |
45
- | `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.74:1 | ✅ pass |
46
- | `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.16:1 | ✅ pass |
47
- | `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.29:1 | ✅ pass |
48
- | `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.39:1 | ✅ pass |
49
- | `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.09:1 | ✅ pass |
50
- | `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.60:1 | ✅ pass |
51
- | `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.74:1 | ✅ pass |
52
- | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.32:1 | ✅ pass |
53
- | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.96:1 | ✅ pass |
54
- | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.18:1 | ✅ pass |
55
- | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.71:1 | ✅ pass |
56
- | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.18:1 | ✅ pass |
57
- | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.71:1 | ✅ pass |
58
- | `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | ✅ pass |
59
- | `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | ✅ pass |
60
- | `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | ✅ pass |
61
- | `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | ✅ pass |
62
- | `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.39:1 | ℹ️ not gated |
41
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
42
+ | --- | --- | --- | --- | --- | --- | --- |
43
+ | `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.98:1 | Lc 99 | ✅ pass |
44
+ | `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.80:1 | Lc 106 | ✅ pass |
45
+ | `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.74:1 | Lc 94 | ✅ pass |
46
+ | `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.16:1 | Lc 91 | ✅ pass |
47
+ | `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.29:1 | Lc 98 | ✅ pass |
48
+ | `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.39:1 | Lc 87 | ✅ pass |
49
+ | `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.09:1 | Lc 71 | ✅ pass |
50
+ | `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.60:1 | Lc 78 | ✅ pass |
51
+ | `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.74:1 | Lc 67 | ✅ pass |
52
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.32:1 | Lc 75 | ✅ pass |
53
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.96:1 | Lc 82 | ✅ pass |
54
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.18:1 | Lc 79 | ✅ pass |
55
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.71:1 | Lc 67 | ✅ pass |
56
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.18:1 | Lc 73 | ✅ pass |
57
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.71:1 | Lc 67 | ✅ pass |
58
+ | `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | Lc 75 | ✅ pass |
59
+ | `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | Lc 78 | ✅ pass |
60
+ | `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | Lc 79 | ✅ pass |
61
+ | `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | Lc 78 | ✅ pass |
62
+ | `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.39:1 | Lc 47 | ℹ️ not gated |
63
63
 
64
64
  ## Dark theme
65
65
 
66
- | Foreground | Background | Role | Held to | Ratio | Verdict |
67
- | --- | --- | --- | --- | --- | --- |
68
- | `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 18.76:1 | ✅ pass |
69
- | `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 17.47:1 | ✅ pass |
70
- | `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 15.55:1 | ✅ pass |
71
- | `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 12.04:1 | ✅ pass |
72
- | `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 11.22:1 | ✅ pass |
73
- | `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.98:1 | ✅ pass |
74
- | `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.69:1 | ✅ pass |
75
- | `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.30:1 | ✅ pass |
76
- | `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.72:1 | ✅ pass |
77
- | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.88:1 | ✅ pass |
78
- | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.41:1 | ✅ pass |
79
- | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.95:1 | ✅ pass |
80
- | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.95:1 | ✅ pass |
81
- | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.55:1 | ✅ pass |
82
- | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.95:1 | ✅ pass |
83
- | `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 8.70:1 | ✅ pass |
84
- | `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 10.66:1 | ✅ pass |
85
- | `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.00:1 | ✅ pass |
86
- | `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 8.41:1 | ✅ pass |
87
- | `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.01:1 | ℹ️ not gated |
66
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
67
+ | --- | --- | --- | --- | --- | --- | --- |
68
+ | `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.01:1 | Lc 91 | ✅ pass |
69
+ | `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.65:1 | Lc 90 | ✅ pass |
70
+ | `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.44:1 | Lc 89 | ✅ pass |
71
+ | `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.20:1 | Lc 73 | ✅ pass |
72
+ | `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.19:1 | Lc 72 | ✅ pass |
73
+ | `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.28:1 | Lc 71 | ✅ pass |
74
+ | `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.16:1 | Lc 50 | ✅ pass |
75
+ | `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.52:1 | Lc 49 | ✅ pass |
76
+ | `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 5.94:1 | Lc 48 | ✅ pass |
77
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.14:1 | Lc 45 | ✅ pass |
78
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 5.58:1 | Lc 44 | ✅ pass |
79
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.95:1 | Lc 43 | ✅ pass |
80
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.31:1 | Lc 40 | ✅ pass |
81
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 4.83:1 | Lc 39 | ✅ pass |
82
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.31:1 | Lc 40 | ✅ pass |
83
+ | `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 7.58:1 | Lc 57 | ✅ pass |
84
+ | `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 9.29:1 | Lc 67 | ✅ pass |
85
+ | `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 5.23:1 | Lc 42 | ✅ pass |
86
+ | `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 7.33:1 | Lc 55 | ✅ pass |
87
+ | `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.29:1 | Lc 15 | ℹ️ not gated |
88
+
89
+ ## Display colorways (skins)
90
+
91
+ The opt-in `data-bronto-skin` colorways (`@ponchia/ui/css/skins.css`,
92
+ authored in `tokens/skins.js`) re-point the one accent to a different single
93
+ hue. Because a shipped colorway is part of the framework — not an arbitrary
94
+ consumer re-brand — **its accent is gated to the same floors as the core**:
95
+ the primary-button label, accent-as-text, and the focus ring/accent fill. Only
96
+ the accent-touching pairings are shown (a skin leaves the canvas and status
97
+ palette untouched). Accents are authored in OKLCH; `--accent-text` is the
98
+ `color-mix`-derived `--accent-strong`, exactly as in the core palette.
99
+
100
+ ### Amber CRT — light
101
+
102
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
103
+ | --- | --- | --- | --- | --- | --- | --- |
104
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.75:1 | Lc 79 | ✅ pass |
105
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 7.44:1 | Lc 86 | ✅ pass |
106
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.66:1 | Lc 83 | ✅ pass |
107
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.14:1 | Lc 71 | ✅ pass |
108
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.66:1 | Lc 78 | ✅ pass |
109
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.14:1 | Lc 71 | ✅ pass |
110
+
111
+ ### Amber CRT — dark
112
+
113
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
114
+ | --- | --- | --- | --- | --- | --- | --- |
115
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 11.57:1 | Lc 75 | ✅ pass |
116
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 10.52:1 | Lc 74 | ✅ pass |
117
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 11.88:1 | Lc 72 | ✅ pass |
118
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.60:1 | Lc 70 | ✅ pass |
119
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 9.64:1 | Lc 69 | ✅ pass |
120
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.60:1 | Lc 70 | ✅ pass |
121
+
122
+ ### E-ink — light
123
+
124
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
125
+ | --- | --- | --- | --- | --- | --- | --- |
126
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.23:1 | Lc 93 | ✅ pass |
127
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 13.47:1 | Lc 100 | ✅ pass |
128
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 11.74:1 | Lc 101 | ✅ pass |
129
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.66:1 | Lc 90 | ✅ pass |
130
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.74:1 | Lc 97 | ✅ pass |
131
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.66:1 | Lc 90 | ✅ pass |
132
+
133
+ ### E-ink — dark
134
+
135
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
136
+ | --- | --- | --- | --- | --- | --- | --- |
137
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.47:1 | Lc 79 | ✅ pass |
138
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.35:1 | Lc 78 | ✅ pass |
139
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 12.86:1 | Lc 76 | ✅ pass |
140
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 11.48:1 | Lc 74 | ✅ pass |
141
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 10.44:1 | Lc 73 | ✅ pass |
142
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 11.48:1 | Lc 74 | ✅ pass |
143
+
144
+ ### Phosphor Green — light
145
+
146
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
147
+ | --- | --- | --- | --- | --- | --- | --- |
148
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.22:1 | Lc 77 | ✅ pass |
149
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.85:1 | Lc 83 | ✅ pass |
150
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.19:1 | Lc 81 | ✅ pass |
151
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.71:1 | Lc 69 | ✅ pass |
152
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.19:1 | Lc 75 | ✅ pass |
153
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.71:1 | Lc 69 | ✅ pass |
154
+
155
+ ### Phosphor Green — dark
156
+
157
+ | Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
158
+ | --- | --- | --- | --- | --- | --- | --- |
159
+ | `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.97:1 | Lc 82 | ✅ pass |
160
+ | `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.80:1 | Lc 81 | ✅ pass |
161
+ | `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 13.75:1 | Lc 80 | ✅ pass |
162
+ | `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 12.27:1 | Lc 79 | ✅ pass |
163
+ | `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.16:1 | Lc 78 | ✅ pass |
164
+ | `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 12.27:1 | Lc 79 | ✅ pass |
165
+
166
+ ## Data-viz palette (advisory)
167
+
168
+ The opt-in Tier-4 chart palette (`@ponchia/ui/css/dataviz.css`, authored in
169
+ `tokens/charts.js`) is gated differently: categorical series are held to
170
+ **mutual distinguishability under normal + simulated protan/deutan/tritan
171
+ vision** (`check:charts`, OKLab ΔE), and colour is **never the sole signal** —
172
+ each series ships a matching `--chart-pattern-*` dot-matrix fill. So the
173
+ WCAG ratios below are **advisory** (a chart fill is not body text); use them to
174
+ pick a darker series for thin lines/points, or rely on the pattern. Series 1 is
175
+ the brand accent.
176
+
177
+ ### Light theme — categorical vs `--bg`
178
+
179
+ | Series | Colour | Ratio _(advisory)_ | APCA _(advisory)_ |
180
+ | --- | --- | --- | --- |
181
+ | 1 _(accent)_ | `#d71921` | 4.71:1 | Lc 67 |
182
+ | 2 | `#e69f00` | 2.05:1 | Lc 37 |
183
+ | 3 | `#56b4e9` | 2.10:1 | Lc 39 |
184
+ | 4 | `#009e73` | 3.11:1 | Lc 54 |
185
+ | 5 | `#f0e442` | 1.20:1 | Lc 9 |
186
+ | 6 | `#0072b2` | 4.71:1 | Lc 68 |
187
+ | 7 | `#cc79a7` | 2.78:1 | Lc 51 |
188
+ | 8 | `#4d5358` | 7.08:1 | Lc 80 |
189
+
190
+ ### Dark theme — categorical vs `--bg`
191
+
192
+ | Series | Colour | Ratio _(advisory)_ | APCA _(advisory)_ |
193
+ | --- | --- | --- | --- |
194
+ | 1 _(accent)_ | `#ff3b41` | 5.31:1 | Lc 40 |
195
+ | 2 | `#e69f00` | 8.32:1 | Lc 58 |
196
+ | 3 | `#56b4e9` | 8.12:1 | Lc 56 |
197
+ | 4 | `#009e73` | 5.48:1 | Lc 40 |
198
+ | 5 | `#f0e442` | 14.17:1 | Lc 87 |
199
+ | 6 | `#0072b2` | 3.61:1 | Lc 26 |
200
+ | 7 | `#cc79a7` | 6.12:1 | Lc 44 |
201
+ | 8 | `#4d5358` | 2.40:1 | Lc 14 |
88
202
 
89
203
  ## Scope & caveats
90
204
 
91
- - This gates the **framework token contract**, not arbitrary consumer
92
- re-brands. Re-accenting via `--accent` is your contrast obligation
93
- (see [theming.md](theming.md) → "Re-brand obligations"); this table is
94
- the guarantee for the *shipped* palettes only.
205
+ - This gates the **framework token contract** (core palette **and** every
206
+ shipped colorway), not arbitrary consumer re-brands. Re-accenting via
207
+ `--accent` yourself is your contrast obligation (see [theming.md](theming.md)
208
+ → "Re-brand obligations"); this table is the guarantee for the *shipped*
209
+ palettes and skins only.
95
210
  - Status colours (`--success` / `--warning` / `--danger`) are gated
96
211
  as **indicators** (3:1). If you set status text *as body copy* on a
97
212
  surface, verify 4.5:1 yourself or pair it with an icon/label.
98
- - Ratios are sRGB WCAG 2.1. The newer APCA model is intentionally not
99
- used WCAG 2.1 AA is the testable legal/again-axe baseline the e2e
100
- suite already asserts.
213
+ - The gated **Ratio** is sRGB WCAG 2.1 AA the testable legal / axe-compatible
214
+ baseline the e2e suite also asserts. The **APCA** column (APCA-W3 0.1.9 `Lc`)
215
+ is **advisory only**: a perceptual cross-check that, unlike WCAG 2.1's
216
+ symmetric ratio, accounts for polarity and is the WCAG 3 candidate. It does
217
+ **not** gate the build while WCAG 3 is a Working Draft — use it to tune
218
+ quality, not to override the WCAG 2.1 floor. As a rough read, body text wants
219
+ `Lc` ≥ 75 and non-text/large ≥ 45–60.
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
- - 262 classes across 109 component groups
12
+ - 303 classes across 121 component groups
13
13
  - Import the typed registry: `import { cls, ui, cx } from '@ponchia/ui/classes'`
14
14
  - Tokens as data: `import { cssVars, tokens, themeColor } from '@ponchia/ui/tokens'`
15
15
 
@@ -179,6 +179,18 @@ each one matches a real selector in the stylesheet.
179
179
  | `cls.breadcrumb` | `ui-breadcrumb` | base |
180
180
  | `cls.breadcrumbItem` | `ui-breadcrumb__item` | part |
181
181
 
182
+ ### `.ui-break-after`
183
+
184
+ | Registry key | Class | Kind |
185
+ | --- | --- | --- |
186
+ | `cls.breakAfter` | `ui-break-after` | base |
187
+
188
+ ### `.ui-break-before`
189
+
190
+ | Registry key | Class | Kind |
191
+ | --- | --- | --- |
192
+ | `cls.breakBefore` | `ui-break-before` | base |
193
+
182
194
  ### `.ui-button`
183
195
 
184
196
  | Registry key | Class | Kind |
@@ -226,6 +238,21 @@ each one matches a real selector in the stylesheet.
226
238
  | --- | --- | --- |
227
239
  | `cls.center` | `ui-center` | base |
228
240
 
241
+ ### `.ui-chart`
242
+
243
+ | Registry key | Class | Kind |
244
+ | --- | --- | --- |
245
+ | `cls.chart` | `ui-chart` | base |
246
+ | `cls.chartBar` | `ui-chart__bar` | part |
247
+ | `cls.chartCaption` | `ui-chart__caption` | part |
248
+ | `cls.chartFallback` | `ui-chart__fallback` | part |
249
+ | `cls.chartFill` | `ui-chart__fill` | part |
250
+ | `cls.chartLabel` | `ui-chart__label` | part |
251
+ | `cls.chartLegend` | `ui-chart__legend` | part |
252
+ | `cls.chartPlot` | `ui-chart__plot` | part |
253
+ | `cls.chartSwatch` | `ui-chart__swatch` | part |
254
+ | `cls.chartTrack` | `ui-chart__track` | part |
255
+
229
256
  ### `.ui-check`
230
257
 
231
258
  | Registry key | Class | Kind |
@@ -393,6 +420,12 @@ each one matches a real selector in the stylesheet.
393
420
  | `cls.hint` | `ui-hint` | base |
394
421
  | `cls.hintError` | `ui-hint--error` | modifier |
395
422
 
423
+ ### `.ui-icon`
424
+
425
+ | Registry key | Class | Kind |
426
+ | --- | --- | --- |
427
+ | `cls.icon` | `ui-icon` | base |
428
+
396
429
  ### `.ui-input`
397
430
 
398
431
  | Registry key | Class | Kind |
@@ -420,6 +453,12 @@ each one matches a real selector in the stylesheet.
420
453
  | --- | --- | --- |
421
454
  | `cls.kbd` | `ui-kbd` | base |
422
455
 
456
+ ### `.ui-keep`
457
+
458
+ | Registry key | Class | Kind |
459
+ | --- | --- | --- |
460
+ | `cls.keep` | `ui-keep` | base |
461
+
423
462
  ### `.ui-key-value`
424
463
 
425
464
  | Registry key | Class | Kind |
@@ -547,6 +586,18 @@ each one matches a real selector in the stylesheet.
547
586
  | --- | --- | --- |
548
587
  | `cls.popover` | `ui-popover` | base |
549
588
 
589
+ ### `.ui-print-exact`
590
+
591
+ | Registry key | Class | Kind |
592
+ | --- | --- | --- |
593
+ | `cls.printExact` | `ui-print-exact` | base |
594
+
595
+ ### `.ui-print-only`
596
+
597
+ | Registry key | Class | Kind |
598
+ | --- | --- | --- |
599
+ | `cls.printOnly` | `ui-print-only` | base |
600
+
550
601
  ### `.ui-progress`
551
602
 
552
603
  | Registry key | Class | Kind |
@@ -581,12 +632,56 @@ each one matches a real selector in the stylesheet.
581
632
  | --- | --- | --- |
582
633
  | `cls.ratio` | `ui-ratio` | base |
583
634
 
635
+ ### `.ui-report`
636
+
637
+ | Registry key | Class | Kind |
638
+ | --- | --- | --- |
639
+ | `cls.report` | `ui-report` | base |
640
+ | `cls.reportAppendix` | `ui-report__appendix` | part |
641
+ | `cls.reportCaption` | `ui-report__caption` | part |
642
+ | `cls.reportCover` | `ui-report__cover` | part |
643
+ | `cls.reportCoverCompact` | `ui-report__cover--compact` | modifier |
644
+ | `cls.reportEvidence` | `ui-report__evidence` | part |
645
+ | `cls.reportFigure` | `ui-report__figure` | part |
646
+ | `cls.reportFinding` | `ui-report__finding` | part |
647
+ | `cls.reportFootnotes` | `ui-report__footnotes` | part |
648
+ | `cls.reportHeader` | `ui-report__header` | part |
649
+ | `cls.reportMeta` | `ui-report__meta` | part |
650
+ | `cls.reportSection` | `ui-report__section` | part |
651
+ | `cls.reportSectionUnnumbered` | `ui-report__section--unnumbered` | modifier |
652
+ | `cls.reportSectionHead` | `ui-report__section-head` | part |
653
+ | `cls.reportSources` | `ui-report__sources` | part |
654
+ | `cls.reportSubtitle` | `ui-report__subtitle` | part |
655
+ | `cls.reportSummary` | `ui-report__summary` | part |
656
+ | `cls.reportTitle` | `ui-report__title` | part |
657
+ | `cls.reportToc` | `ui-report__toc` | part |
658
+ | `cls.reportCompact` | `ui-report--compact` | modifier |
659
+ | `cls.reportNumbered` | `ui-report--numbered` | modifier |
660
+
584
661
  ### `.ui-reveal`
585
662
 
586
663
  | Registry key | Class | Kind |
587
664
  | --- | --- | --- |
588
665
  | `cls.reveal` | `ui-reveal` | base |
589
666
 
667
+ ### `.ui-screen-only`
668
+
669
+ | Registry key | Class | Kind |
670
+ | --- | --- | --- |
671
+ | `cls.screenOnly` | `ui-screen-only` | base |
672
+
673
+ ### `.ui-scroll-progress`
674
+
675
+ | Registry key | Class | Kind |
676
+ | --- | --- | --- |
677
+ | `cls.scrollProgress` | `ui-scroll-progress` | base |
678
+
679
+ ### `.ui-scroll-reveal`
680
+
681
+ | Registry key | Class | Kind |
682
+ | --- | --- | --- |
683
+ | `cls.scrollReveal` | `ui-scroll-reveal` | base |
684
+
590
685
  ### `.ui-search`
591
686
 
592
687
  | Registry key | Class | Kind |
@@ -826,6 +921,12 @@ each one matches a real selector in the stylesheet.
826
921
  | --- | --- | --- |
827
922
  | `cls.visuallyHidden` | `ui-visually-hidden` | base |
828
923
 
924
+ ### `.ui-vt`
925
+
926
+ | Registry key | Class | Kind |
927
+ | --- | --- | --- |
928
+ | `cls.vt` | `ui-vt` | base |
929
+
829
930
  ## Table-local state classes
830
931
 
831
932
  Not in `cls` by design — these are plain `is-*` state hooks scoped to
@@ -913,10 +1014,10 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
913
1014
  | `--z-overlay` | `30` |
914
1015
  | `--z-popover` | `50` |
915
1016
  | `--z-toast` | `60` |
916
- | `--accent-1` | `color-mix(in srgb, var(--accent) 8%, var(--bg))` |
917
- | `--accent-2` | `color-mix(in srgb, var(--accent) 16%, var(--bg))` |
918
- | `--accent-3` | `color-mix(in srgb, var(--accent) 32%, var(--bg))` |
919
- | `--accent-4` | `color-mix(in srgb, var(--accent) 60%, var(--bg))` |
1017
+ | `--accent-1` | `color-mix(in oklch, var(--accent) 8%, var(--accent-ramp-end))` |
1018
+ | `--accent-2` | `color-mix(in oklch, var(--accent) 16%, var(--accent-ramp-end))` |
1019
+ | `--accent-3` | `color-mix(in oklch, var(--accent) 32%, var(--accent-ramp-end))` |
1020
+ | `--accent-4` | `color-mix(in oklch, var(--accent) 60%, var(--accent-ramp-end))` |
920
1021
  | `--accent-5` | `var(--accent)` |
921
1022
  | `--accent-6` | `var(--accent-strong)` |
922
1023
  | `--surface-1` | `var(--bg)` |
@@ -961,6 +1062,7 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
961
1062
  | `--text-soft` | `#353533` |
962
1063
  | `--text-dim` | `#686863` |
963
1064
  | `--accent` | `#d71921` |
1065
+ | `--accent-ramp-end` | `#ffffff` |
964
1066
  | `--accent-strong` | `color-mix(in srgb, var(--accent) 83%, #000)` |
965
1067
  | `--accent-text` | `var(--accent-strong)` |
966
1068
  | `--accent-soft` | `color-mix(in srgb, var(--accent) 10%, transparent)` |
@@ -968,8 +1070,6 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
968
1070
  | `--success-soft` | `rgb(47, 125, 79, 0.12)` |
969
1071
  | `--warning` | `#806414` |
970
1072
  | `--warning-soft` | `rgb(128, 100, 20, 0.13)` |
971
- | `--orange` | `#a85f32` |
972
- | `--orange-soft` | `rgb(168, 95, 50, 0.13)` |
973
1073
  | `--danger` | `#c01622` |
974
1074
  | `--danger-soft` | `rgb(192, 22, 34, 0.1)` |
975
1075
  | `--info` | `#1f63c4` |
@@ -987,18 +1087,19 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
987
1087
 
988
1088
  | Token | Value |
989
1089
  | --- | --- |
990
- | `--bg` | `#000000` |
991
- | `--bg-elevated` | `#0a0a0a` |
1090
+ | `--bg` | `#121212` |
1091
+ | `--bg-elevated` | `#181818` |
992
1092
  | `--bg-accent` | `color-mix(in srgb, var(--accent) 8%, transparent)` |
993
- | `--panel` | `#0c0c0c` |
994
- | `--panel-strong` | `#141414` |
995
- | `--panel-soft` | `#1a1a1a` |
996
- | `--line` | `#2a2a2a` |
997
- | `--line-strong` | `#444444` |
998
- | `--text` | `#f2f2f2` |
999
- | `--text-soft` | `#c4c4c4` |
1000
- | `--text-dim` | `#858585` |
1093
+ | `--panel` | `#1c1c1c` |
1094
+ | `--panel-strong` | `#222222` |
1095
+ | `--panel-soft` | `#242424` |
1096
+ | `--line` | `#383838` |
1097
+ | `--line-strong` | `#555555` |
1098
+ | `--text` | `#e6e6e6` |
1099
+ | `--text-soft` | `#c8c8c8` |
1100
+ | `--text-dim` | `#a0a0a0` |
1001
1101
  | `--accent` | `#ff3b41` |
1102
+ | `--accent-ramp-end` | `#000000` |
1002
1103
  | `--accent-strong` | `color-mix(in srgb, var(--accent) 84%, #fff)` |
1003
1104
  | `--accent-text` | `var(--accent-strong)` |
1004
1105
  | `--accent-soft` | `color-mix(in srgb, var(--accent) 14%, transparent)` |
@@ -1006,8 +1107,6 @@ Exact mirror of the `:root` blocks in `css/tokens.css`
1006
1107
  | `--success-soft` | `rgb(78, 194, 126, 0.14)` |
1007
1108
  | `--warning` | `#d8bd72` |
1008
1109
  | `--warning-soft` | `rgb(216, 189, 114, 0.14)` |
1009
- | `--orange` | `#d08c5b` |
1010
- | `--orange-soft` | `rgb(208, 140, 91, 0.15)` |
1011
1110
  | `--danger` | `#ff4d54` |
1012
1111
  | `--danger-soft` | `rgb(255, 77, 84, 0.15)` |
1013
1112
  | `--info` | `#6fb0e6` |