@wildmason/aegis 1.14.1 → 1.16.0
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 +309 -0
- package/inputs.css +78 -0
- package/package.json +6 -3
- package/themes.css +12 -12
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@wildmason/aegis` are recorded here, following
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
This file was started on 2026-09-01, later than it should have been. Entries
|
|
8
|
+
from 1.8.0 onward are backfilled from the release commits and the project health
|
|
9
|
+
page; both were written at the time, so the entries are sourced rather than
|
|
10
|
+
reconstructed from memory. Anything before 1.8.0 lives in `git log` only, and is
|
|
11
|
+
deliberately not summarised here rather than guessed at.
|
|
12
|
+
|
|
13
|
+
**Releases 1.12.0 through 1.14.1 carry no git tag.** They were published through
|
|
14
|
+
the GitHub OIDC workflow, which does not tag, so `git tag` skips from `v1.11.0` to
|
|
15
|
+
`v1.15.0`, and the tag names before that are inconsistent (`1.4.4`, `v1.5.1`).
|
|
16
|
+
Version links below are omitted where no tag exists rather than pointed at a URL
|
|
17
|
+
that 404s.
|
|
18
|
+
|
|
19
|
+
## [Unreleased]
|
|
20
|
+
|
|
21
|
+
_No unreleased changes._
|
|
22
|
+
|
|
23
|
+
## [1.16.0] - 2026-09-01
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- `.wm-kbd--on-accent` — the key cap for an accent fill. The base `.wm-kbd` is
|
|
28
|
+
`--wm-bg-sunken` inside `--wm-border-input`: a recess in a *surface*, and both
|
|
29
|
+
tokens are wrong the moment the cap sits on `.wm-btn--primary`. The modifier
|
|
30
|
+
carries no fill of its own, so the cap's label **is** the button's label and
|
|
31
|
+
inherits the contrast that pair already guarantees; only its edge is new, drawn
|
|
32
|
+
as `--wm-color-accent-text` at 75% over whatever is behind. Mixing toward
|
|
33
|
+
`transparent` rather than toward `--wm-color-accent` is what lets one
|
|
34
|
+
declaration serve the rest fill and the hover fill both.
|
|
35
|
+
- `check:accent-contrast` — measures `.wm-btn--primary`'s label on both of its
|
|
36
|
+
fills, the new cap's edge on both, and how far the hover fill sits from the rest
|
|
37
|
+
fill, across every theme. Its destructive twin has had a guard since
|
|
38
|
+
white-on-danger was caught failing 8 of 12 themes; the accent button is the same
|
|
39
|
+
shape and had none.
|
|
40
|
+
|
|
41
|
+
The separation bar is there because the first pass shipped without one and eight
|
|
42
|
+
hovers came out invisible: the derivation took the smallest lightness step that
|
|
43
|
+
cleared contrast, which is a hover nobody can see. It is expressed as a Weber
|
|
44
|
+
fraction, `|L_hover - L_rest| / L_rest >= 0.14`, because an ABSOLUTE distance
|
|
45
|
+
cannot separate the accepted values from the rejected ones at any threshold —
|
|
46
|
+
sorted by OKLab distance an accepted theme sits below a rejected one. Normalised
|
|
47
|
+
by the rest fill's own lightness they separate cleanly, and 0.14 is the low end
|
|
48
|
+
of the band occupied by the three hovers this repo already shipped and nobody
|
|
49
|
+
ever complained about.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **`.wm-btn--primary:hover` failed WCAG AA on warm-light: white on
|
|
54
|
+
`--wm-color-accent-hover` `#2aa198` measured 3.16:1.** The cause was
|
|
55
|
+
structural rather than one bad value. On five themes the hover was the
|
|
56
|
+
palette's *second accent* rather than a lighter or darker step of the first
|
|
57
|
+
— Solarized cyan behind Solarized blue, Dracula pink behind Dracula purple,
|
|
58
|
+
Monokai orange behind Monokai magenta. A hue jump promises nothing about the
|
|
59
|
+
label riding on it, so the label's contrast was whatever the two palette
|
|
60
|
+
entries happened to be, and on hover it also missed APCA Lc 60 on nine themes,
|
|
61
|
+
as low as Lc 28.7. Nine hover values are now the accent's own hue and chroma at
|
|
62
|
+
a different OKLCh lightness, moved *away* from the label, far enough to clear the
|
|
63
|
+
separation bar as well as the contrast bars. Where sRGB cannot hold the accent's
|
|
64
|
+
chroma at the higher lightness — vampires-kiss and twilight-peach — the colour
|
|
65
|
+
is gamut mapped with hue and lightness held and chroma reduced, rather than
|
|
66
|
+
clamped per channel, which shifts hue.
|
|
67
|
+
- `--wm-color-accent-text` on arctic-night, vampires-kiss and twilight-peach was
|
|
68
|
+
short of APCA Lc 60 on the rest fill by 0.1, 0.3 and 1.4. Each moved a little
|
|
69
|
+
further from its fill in OKLCh lightness — hue and chroma held, two of the
|
|
70
|
+
three by under five values out of 255.
|
|
71
|
+
- `DESIGN_LANGUAGE.md` §13 claimed `.wm-kbd` was "used identically in Helm
|
|
72
|
+
(command palette) and Slate (sidebar search button)". Neither consumer used it
|
|
73
|
+
at all. Helm draws seven key badges from five component-local rules; Slate draws
|
|
74
|
+
none. `check:docs` gates class *existence* in both directions and cannot see a
|
|
75
|
+
false claim about who uses one, so this was found by looking.
|
|
76
|
+
|
|
77
|
+
### Known limitation
|
|
78
|
+
|
|
79
|
+
- **Four accents cannot reach APCA Lc 60 with any label, and are pinned rather
|
|
80
|
+
than repaired. All four clear WCAG on both fills** — WCAG is the bar this
|
|
81
|
+
package ships to and no theme is exempt from it; APCA Lc 60 is the bar it
|
|
82
|
+
reaches for, enforced the same way because a bar nothing enforces decays. A
|
|
83
|
+
pinned theme is behind an aspiration, not broken. Pure white and pure black bracket every achievable Lc, and on
|
|
84
|
+
posh-sandalwood (`#f92672`, best 40.7 dark / 68.8 white — but white measures
|
|
85
|
+
3.79:1 and fails WCAG outright), source-control-dark (`#3fb950`, 54.6),
|
|
86
|
+
crepuscular-sky (`#c09d06`, 55.7) and wildmason (`#82a682`, 57.8), neither end
|
|
87
|
+
reaches it. Clearing the bar means changing the accent itself, which is each
|
|
88
|
+
theme's brand colour. The shortfalls are recorded to one decimal in
|
|
89
|
+
`check-accent-contrast.mjs`, which fails if one drifts in either direction.
|
|
90
|
+
|
|
91
|
+
## [1.15.0] - 2026-09-01
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- `.wm-input--error` — the invalid state for `.wm-input` and `.wm-input-group`.
|
|
96
|
+
It was documented in prose and in a live demo on the inputs guide page and had
|
|
97
|
+
never existed, so the demo captioned "error state" rendered a field identical
|
|
98
|
+
to a valid one. It fills with `--wm-color-danger-bg` and rims with
|
|
99
|
+
`--wm-color-danger-border`, the same tokens as the `.wm-error-msg` block below
|
|
100
|
+
the field, and yields to `:focus` so an accent border is never fighting a red
|
|
101
|
+
one while the user is fixing the field. Pair it with `.wm-error-msg` and
|
|
102
|
+
`aria-invalid="true"`: colour must not be the only signal.
|
|
103
|
+
- `scripts/check-design-language.mjs`, wired into `npm run build` as
|
|
104
|
+
`check:docs`. It holds all 32 agent-visible documents — `DESIGN_LANGUAGE.md`
|
|
105
|
+
plus the guide pages in `mcp/guide-index.json` — to the CSS this package
|
|
106
|
+
actually ships, in both directions: a name no CSS defines, and a shipped
|
|
107
|
+
`.wm-*` class no document mentions.
|
|
108
|
+
|
|
109
|
+
### Changed
|
|
110
|
+
|
|
111
|
+
- `check:semantic-contrast` measures a fourth recipe and a fourth surface. The
|
|
112
|
+
new pair is `--wm-text-primary` on the danger tint, which is what
|
|
113
|
+
`.wm-input--error` paints and which no bar covered, because every other status
|
|
114
|
+
recipe reads `--wm-color-<tone>-readable` on the tint. `bg-sunken` joins the
|
|
115
|
+
surface sweep, since both `.wm-input:hover` and `.wm-input-group:hover` fill
|
|
116
|
+
with it. 144 combinations became 192; all pass.
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
|
|
120
|
+
- `DESIGN_LANGUAGE.md` had never been migrated through the background-token
|
|
121
|
+
rename. It prescribed `--wm-bg-inset`, `--wm-bg-canvas` and `--wm-bg-surface`,
|
|
122
|
+
which became `sunken` / `base` / `raised`+`float` — so a consumer following the
|
|
123
|
+
spec wrote a `var()` naming an undefined property, which makes the whole
|
|
124
|
+
declaration invalid and apply to nothing, silently. Corrected against the
|
|
125
|
+
shipped CSS rather than by find-and-replace, since `surface` split in two.
|
|
126
|
+
- §13 taught eight lines of inline style for a keyboard badge. `.wm-kbd` and
|
|
127
|
+
`.wm-kbd-combo` had shipped all along; the spec now names them.
|
|
128
|
+
- §6 documented `.btn-primary`, `.btn-secondary`, `.btn-ghost` and `.btn-danger`
|
|
129
|
+
— classes this package has never shipped. It now documents `.wm-btn` with its
|
|
130
|
+
real variants, including `--flat` and `--xs`, which were undocumented.
|
|
131
|
+
- §15.1 listed `.wm-focus` and `.wm-focus-inset` utility classes that do not
|
|
132
|
+
exist. Every shipped control already carries its own `:focus-visible` rule; the
|
|
133
|
+
section now says which treatment goes with which fill.
|
|
134
|
+
- §17 presented twelve syntax, diff and code tokens as part of the token set.
|
|
135
|
+
Nine syntax tokens ship; the other twelve are app-local and were never
|
|
136
|
+
promoted. They are now listed as names to avoid, with the promotion path.
|
|
137
|
+
- §20 was still a roadmap for a package that had shipped, and was the source of
|
|
138
|
+
several of the names above.
|
|
139
|
+
- `docs/token-migration.md` stated that `--wm-bg-sunken` is the darkest colour in
|
|
140
|
+
every theme. Measured across all twelve theme blocks, it is the **lightest** in
|
|
141
|
+
`warm-light`, `neutral-light` and `solarized-precision`, and `sage-linen`
|
|
142
|
+
follows neither convention on purpose.
|
|
143
|
+
- The inputs guide's `.wm-class` placeholder and encapsulation example named
|
|
144
|
+
classes that do not exist.
|
|
145
|
+
|
|
146
|
+
### Known limitation
|
|
147
|
+
|
|
148
|
+
- `.wm-input--error` measures APCA **Lc 60.3** on `solarized-precision` over
|
|
149
|
+
`--wm-bg-float`, against a bar of 60. It passes both bars on all twelve themes
|
|
150
|
+
(worst WCAG 6.20:1), but the margin is thin, and 1.13.0 set a precedent of
|
|
151
|
+
tuning to Lc 61 because Lc 60.0 can be flipped by a single hex rounding. The
|
|
152
|
+
tint reduces contrast on every one of the 192 combinations by construction, so
|
|
153
|
+
closing the margin would mean retuning a shipped token. Accepted deliberately
|
|
154
|
+
rather than overlooked; `check:semantic-contrast` will fail if it slips.
|
|
155
|
+
|
|
156
|
+
## [1.14.1] - 2026-08-27
|
|
157
|
+
|
|
158
|
+
### Fixed
|
|
159
|
+
|
|
160
|
+
- Five theme/tone pairs shipped at 1.08:1 to 1.38:1 because a guard asserted the
|
|
161
|
+
fallback it was checking. `themes.css` selects its default as
|
|
162
|
+
`:root, [data-theme='warm-light']`, so that block is both the warm-light theme
|
|
163
|
+
and a later bare-`:root` declaration — a theme silent on a token receives
|
|
164
|
+
warm-light's value, not its own tone. Every theme must now declare all four
|
|
165
|
+
`-readable` tokens; `var(--wm-color-<tone>)` is the supported way to say "my
|
|
166
|
+
tone already reads", and the guard resolves and measures it.
|
|
167
|
+
|
|
168
|
+
## [1.14.0] - 2026-08-27
|
|
169
|
+
|
|
170
|
+
### Added
|
|
171
|
+
|
|
172
|
+
- `WmTooltip` — an accessible tooltip directive on a CDK overlay, beside the
|
|
173
|
+
CSS-only `data-tooltip` chip. It shares `aria-describedby` rather than owning
|
|
174
|
+
it, satisfies WCAG 1.4.13 (Escape dismisses without moving focus and without
|
|
175
|
+
stopping the event; the pointer can enter the panel), and has no border by
|
|
176
|
+
measurement — at least 6.67:1 from every surface Aegis can put behind it.
|
|
177
|
+
`wmTooltipFocusable` is opt-in on purpose: never set it inside a
|
|
178
|
+
roving-tabindex container.
|
|
179
|
+
- `check:tooltip-contrast`, a third build gate.
|
|
180
|
+
|
|
181
|
+
### Fixed
|
|
182
|
+
|
|
183
|
+
- Every anchored overlay now stays with its trigger when anything scrolls.
|
|
184
|
+
`createRepositionScrollStrategy` had never fired once: CDK's `ScrollDispatcher`
|
|
185
|
+
listens on the document in the **bubbling** phase and `scroll` does not bubble,
|
|
186
|
+
so in a fixed-height shell with an inner `overflow-y: auto` element both of its
|
|
187
|
+
sources are empty and the strategy is a silent no-op. `wm-popover`,
|
|
188
|
+
`wm-select` and `wm-combobox` had never set a strategy at all. Upgrading is the
|
|
189
|
+
whole fix.
|
|
190
|
+
|
|
191
|
+
## [1.13.0] - 2026-08-27
|
|
192
|
+
|
|
193
|
+
### Changed
|
|
194
|
+
|
|
195
|
+
- `--wm-color-accent-readable` is now declared by all twelve themes and held to
|
|
196
|
+
APCA. On WCAG the accent family looked healthy at 4.5:1 to 6.3:1; on APCA
|
|
197
|
+
eleven of twelve missed Lc 60 on a bare surface and all twelve missed it on the
|
|
198
|
+
accent's own 10% tint. Both pre-existing overrides failed, because both were
|
|
199
|
+
tuned to WCAG alone. Tuned to Lc 61 rather than 60, because tuning to the bar
|
|
200
|
+
exactly put one theme on Lc 60.0.
|
|
201
|
+
|
|
202
|
+
## [1.12.0] - 2026-08-27
|
|
203
|
+
|
|
204
|
+
### Added
|
|
205
|
+
|
|
206
|
+
- `--wm-color-<tone>-readable` for danger, warning and success — 31 overrides
|
|
207
|
+
across 12 themes. The tone is the saturated colour that *names* a status; it
|
|
208
|
+
was never a colour that could be *read*, failing on 31 of 36 theme/tone
|
|
209
|
+
combinations.
|
|
210
|
+
- `--wm-color-accent-border`, used by `.wm-info-msg`.
|
|
211
|
+
- `check:semantic-contrast`, a build gate over every theme/tone/surface
|
|
212
|
+
combination on both contrast models.
|
|
213
|
+
|
|
214
|
+
### Fixed
|
|
215
|
+
|
|
216
|
+
- No status rim had ever met WCAG 1.4.11. `-border` was a 25% mix toward
|
|
217
|
+
`transparent`, measuring 1.18:1 to 1.88:1 on every theme and tone. Rims now use
|
|
218
|
+
the button-edge rule at 65/35 — 70/30 fails at 2.93:1, because a rim has a
|
|
219
|
+
neighbour the edge never had: the tint the block is filled with.
|
|
220
|
+
- Toasts stopped mixing their own 20% tint and took the shared tokens.
|
|
221
|
+
|
|
222
|
+
## [1.11.0] - 2026-08-22
|
|
223
|
+
|
|
224
|
+
### Added
|
|
225
|
+
|
|
226
|
+
- `--wm-color-danger-solid` and `--wm-color-danger-edge`.
|
|
227
|
+
- `check:destructive-contrast`, the first build gate to measure a token *pair*.
|
|
228
|
+
|
|
229
|
+
### Fixed
|
|
230
|
+
|
|
231
|
+
- `.wm-btn--destructive` painted `#ffffff` on `--wm-color-danger`, a token tuned
|
|
232
|
+
for danger as *text*, so the label failed WCAG AA on 8 of 12 themes — worst
|
|
233
|
+
2.74:1. The fill and the 3:1 component boundary now come from separate tokens,
|
|
234
|
+
because on `arctic-night` no single red satisfies both. Only the fill darkens
|
|
235
|
+
on hover; darkening the edge would eat the contrast it exists to guarantee.
|
|
236
|
+
|
|
237
|
+
## [1.10.2] - 2026-08-18
|
|
238
|
+
|
|
239
|
+
### Fixed
|
|
240
|
+
|
|
241
|
+
- The UI token now selects bundled Inter, and the mono token Cascadia Code,
|
|
242
|
+
before OS fallbacks. 1.10.1 packaged every face but still selected Segoe first,
|
|
243
|
+
so asset-presence proof did not prove runtime selection. The build guard now
|
|
244
|
+
checks both.
|
|
245
|
+
|
|
246
|
+
## [1.10.1] - 2026-08-18
|
|
247
|
+
|
|
248
|
+
### Added
|
|
249
|
+
|
|
250
|
+
- The complete typography stack is vendored: Inter and Cascadia Code variable
|
|
251
|
+
WOFF2 faces, normal and italic, with both SIL OFL 1.1 licenses and pinned
|
|
252
|
+
upstream checksums. The docs app no longer downloads a font.
|
|
253
|
+
|
|
254
|
+
## [1.10.0] - 2026-08-09
|
|
255
|
+
|
|
256
|
+
### Added
|
|
257
|
+
|
|
258
|
+
- `WmPopover` accepts a nullable `ariaLabel`, applied to the overlay shell that
|
|
259
|
+
already owns the role and the generated id the trigger's `aria-controls`
|
|
260
|
+
points at. Existing consumers emit no new attribute.
|
|
261
|
+
|
|
262
|
+
## [1.9.2] - 2026-08-09
|
|
263
|
+
|
|
264
|
+
### Fixed
|
|
265
|
+
|
|
266
|
+
- Inactive and unavailable tabs both resolved to `--wm-text-muted`, so
|
|
267
|
+
desaturating neutral text did nothing. Unavailable labels and icons now mix
|
|
268
|
+
muted text to 52% transparency, while focus outlines stay fully opaque.
|
|
269
|
+
|
|
270
|
+
## [1.9.1] - 2026-08-09
|
|
271
|
+
|
|
272
|
+
### Changed
|
|
273
|
+
|
|
274
|
+
- `wm-tab-separator` uses `--wm-border-subtle` and renders as an unfocusable
|
|
275
|
+
`role="separator"` with `aria-orientation="vertical"`, so grouping reaches
|
|
276
|
+
assistive technology without adding a keyboard stop.
|
|
277
|
+
|
|
278
|
+
## [1.9.0] - 2026-08-09
|
|
279
|
+
|
|
280
|
+
### Changed
|
|
281
|
+
|
|
282
|
+
- **BREAKING:** `wm-modal` traps focus itself. Consumers that applied their own
|
|
283
|
+
`cdkTrapFocus` must remove it or they nest a second trap. The removed traps
|
|
284
|
+
were inert, so nobody loses working behaviour: `CdkTrapFocus.ngAfterContentInit`
|
|
285
|
+
calls `attachAnchors()`, which requires a `parentNode`, and projected content
|
|
286
|
+
has none at that moment — measured at 0 anchors before, 2 after.
|
|
287
|
+
- Published through GitHub OIDC Trusted Publishing. No long-lived npm token and
|
|
288
|
+
no 2FA bypass.
|
|
289
|
+
|
|
290
|
+
## [1.8.0] - 2026-08-04
|
|
291
|
+
|
|
292
|
+
### Added
|
|
293
|
+
|
|
294
|
+
- `wm-combobox` gains `ariaLabel` and `ariaLabelledby`. The host is not a
|
|
295
|
+
labelable element and the input had no aria binding, so in multi-select — where
|
|
296
|
+
the placeholder is blanked once a chip renders — it could have no accessible
|
|
297
|
+
name at all. `ariaLabelledby` wins and suppresses `aria-label`, which makes
|
|
298
|
+
WCAG 2.5.3 structurally impossible to violate.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
Releases before 1.8.0 are in `git log`. See also `wiki/products/Aegis - Health.md`
|
|
303
|
+
for the decisions behind these changes, including the ones decided against.
|
|
304
|
+
|
|
305
|
+
[Unreleased]: https://github.com/wildmason/aegis/compare/v1.16.0...HEAD
|
|
306
|
+
[1.16.0]: https://github.com/wildmason/aegis/releases/tag/v1.16.0
|
|
307
|
+
[1.15.0]: https://github.com/wildmason/aegis/releases/tag/v1.15.0
|
|
308
|
+
[1.11.0]: https://github.com/wildmason/aegis/releases/tag/v1.11.0
|
|
309
|
+
[1.9.0]: https://github.com/wildmason/aegis/releases/tag/v1.9.0
|
package/inputs.css
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
.wm-input-group Composite row: icon + .wm-input-bare (e.g. search)
|
|
39
39
|
.wm-input-bare Borderless inner input used inside .wm-input-group
|
|
40
40
|
.wm-input-icon Leading/trailing icon slot inside .wm-input-group
|
|
41
|
+
.wm-input--error Invalid state for .wm-input / .wm-input-group
|
|
41
42
|
.wm-select-trigger Button-based custom select trigger (for app-select etc.)
|
|
42
43
|
.wm-number-input Number input variant (spinner chrome removed)
|
|
43
44
|
.wm-number-controls ± button strip appended to .wm-input-group
|
|
@@ -436,6 +437,38 @@
|
|
|
436
437
|
cursor: not-allowed;
|
|
437
438
|
}
|
|
438
439
|
|
|
440
|
+
/* Invalid: --wm-color-danger-border, the same edge the .wm-error-msg block
|
|
441
|
+
below the field draws, so the field and its message read as one thing.
|
|
442
|
+
The fill is --wm-color-danger-bg rather than a flat tint, because it is
|
|
443
|
+
the only danger background tuned per theme to stay behind text.
|
|
444
|
+
|
|
445
|
+
Kept above :focus in the cascade order deliberately: focus wins while the
|
|
446
|
+
user is fixing the field, so the accent border and its pulse are not
|
|
447
|
+
fighting a red one. The error border comes back the moment focus leaves,
|
|
448
|
+
and the message block never went anywhere.
|
|
449
|
+
|
|
450
|
+
Colour is never the only signal — pair this with .wm-error-msg and
|
|
451
|
+
aria-invalid="true", or a red border is the whole message to a user who
|
|
452
|
+
cannot see red.
|
|
453
|
+
|
|
454
|
+
Each selector is anchored to the element it is for. `.wm-input--error` alone
|
|
455
|
+
would match BOTH a control and a group, and a group is never `:focus` — the
|
|
456
|
+
input inside it is — so the control rule's `:not(:focus)` is vacuously true
|
|
457
|
+
on a group and paints the tint straight through the group rule's
|
|
458
|
+
`:not(:focus-within)`. Measured, not reasoned about: a focused group showed
|
|
459
|
+
the accent border with the error fill still behind it. */
|
|
460
|
+
.wm-input.wm-input--error:not(:focus),
|
|
461
|
+
.wm-input-group.wm-input--error:not(:focus-within) {
|
|
462
|
+
border-color: var(--wm-color-danger-border);
|
|
463
|
+
background-color: var(--wm-color-danger-bg);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.wm-input.wm-input--error:hover:not(:focus):not(:disabled),
|
|
467
|
+
.wm-input-group.wm-input--error:hover:not(:focus-within) {
|
|
468
|
+
border-color: var(--wm-color-danger);
|
|
469
|
+
background-color: var(--wm-color-danger-bg);
|
|
470
|
+
}
|
|
471
|
+
|
|
439
472
|
/* Inherit color-scheme so date/time picker chrome (calendar icon, spinners)
|
|
440
473
|
matches the active theme's light/dark declaration. */
|
|
441
474
|
.wm-input[type='date'],
|
|
@@ -1553,3 +1586,48 @@ select.wm-input {
|
|
|
1553
1586
|
color: var(--wm-text-muted);
|
|
1554
1587
|
pointer-events: none;
|
|
1555
1588
|
}
|
|
1589
|
+
|
|
1590
|
+
/* ----------------------------------------------------------------
|
|
1591
|
+
On an accent fill — .wm-kbd--on-accent
|
|
1592
|
+
----------------------------------------------------------------
|
|
1593
|
+
A plain .wm-kbd is --wm-bg-sunken inside --wm-border-input: a
|
|
1594
|
+
recess in a surface. Put one on .wm-btn--primary and both tokens
|
|
1595
|
+
are answering the wrong question — the fill is a surface colour
|
|
1596
|
+
stranded on the accent, and the border is tuned to separate from
|
|
1597
|
+
surfaces rather than from a saturated fill.
|
|
1598
|
+
|
|
1599
|
+
This modifier carries no fill of its own. It borrows the button's,
|
|
1600
|
+
which means the cap's label IS the button's label and inherits the
|
|
1601
|
+
contrast that pair already guarantees; nothing about the text needs
|
|
1602
|
+
measuring twice. The edge is the label colour at 75% over whatever
|
|
1603
|
+
sits behind it, and mixing toward `transparent` rather than toward
|
|
1604
|
+
a named fill is what lets ONE declaration serve both the rest fill
|
|
1605
|
+
and the hover fill — a mix toward --wm-color-accent could only
|
|
1606
|
+
ever be correct for one of the two.
|
|
1607
|
+
|
|
1608
|
+
75% is held by check-accent-contrast.mjs against both fills on
|
|
1609
|
+
every theme. The binding case is posh-sandalwood, where the edge
|
|
1610
|
+
measures 3.47:1 against WCAG 1.4.11's 3:1.
|
|
1611
|
+
|
|
1612
|
+
Usage — inside an accent button:
|
|
1613
|
+
<button class="wm-btn wm-btn--primary">
|
|
1614
|
+
Accept
|
|
1615
|
+
<span class="wm-kbd-combo">
|
|
1616
|
+
<kbd class="wm-kbd wm-kbd--on-accent">Ctrl</kbd>
|
|
1617
|
+
<kbd class="wm-kbd wm-kbd--on-accent">Enter</kbd>
|
|
1618
|
+
</span>
|
|
1619
|
+
</button>
|
|
1620
|
+
---------------------------------------------------------------- */
|
|
1621
|
+
|
|
1622
|
+
.wm-kbd--on-accent {
|
|
1623
|
+
color: var(--wm-color-accent-text);
|
|
1624
|
+
background: transparent;
|
|
1625
|
+
border-color: color-mix(in srgb, var(--wm-color-accent-text) 75%, transparent);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/* The combo's `+` is --wm-text-muted, a surface colour, so it is as wrong on
|
|
1629
|
+
an accent fill as the cap's own tokens were. Same share as the edge, so
|
|
1630
|
+
there is one number to keep in step rather than two. */
|
|
1631
|
+
.wm-kbd-combo > .wm-kbd--on-accent + .wm-kbd--on-accent::before {
|
|
1632
|
+
color: color-mix(in srgb, currentColor 75%, transparent);
|
|
1633
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wildmason/aegis",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Aegis design system \u00e2\u20ac\u201d CSS tokens and Angular component library",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check:offline-fonts": "node scripts/check-offline-fonts.mjs",
|
|
7
|
-
"build": "npm run check:offline-fonts && npm run check:destructive-contrast && npm run check:semantic-contrast && npm run check:tooltip-contrast && ng-packagr -p ng-package.json",
|
|
7
|
+
"build": "npm run check:offline-fonts && npm run check:destructive-contrast && npm run check:semantic-contrast && npm run check:accent-contrast && npm run check:tooltip-contrast && npm run check:docs && ng-packagr -p ng-package.json",
|
|
8
8
|
"prepublishOnly": "npm run build",
|
|
9
9
|
"check:destructive-contrast": "node scripts/check-destructive-contrast.mjs",
|
|
10
10
|
"check:semantic-contrast": "node scripts/check-semantic-contrast.mjs",
|
|
11
|
-
"check:tooltip-contrast": "node scripts/check-tooltip-contrast.mjs"
|
|
11
|
+
"check:tooltip-contrast": "node scripts/check-tooltip-contrast.mjs",
|
|
12
|
+
"check:accent-contrast": "node scripts/check-accent-contrast.mjs",
|
|
13
|
+
"check:docs": "node scripts/check-design-language.mjs"
|
|
12
14
|
},
|
|
13
15
|
"files": [
|
|
16
|
+
"CHANGELOG.md",
|
|
14
17
|
"dist",
|
|
15
18
|
"fonts",
|
|
16
19
|
"themes.css",
|
package/themes.css
CHANGED
|
@@ -354,7 +354,7 @@
|
|
|
354
354
|
|
|
355
355
|
/* Accent */
|
|
356
356
|
--wm-color-accent: #105987;
|
|
357
|
-
--wm-color-accent-hover: #
|
|
357
|
+
--wm-color-accent-hover: #004771;
|
|
358
358
|
--wm-color-accent-text: #ffffff;
|
|
359
359
|
--wm-color-accent-readable: #004066;
|
|
360
360
|
|
|
@@ -500,8 +500,8 @@
|
|
|
500
500
|
|
|
501
501
|
/* Accent — light teal requires dark text */
|
|
502
502
|
--wm-color-accent: #8fc4d3;
|
|
503
|
-
--wm-color-accent-hover: #
|
|
504
|
-
--wm-color-accent-text: #
|
|
503
|
+
--wm-color-accent-hover: #b2e8f7;
|
|
504
|
+
--wm-color-accent-text: #2c323e;
|
|
505
505
|
--wm-color-accent-readable: #a5dbea;
|
|
506
506
|
|
|
507
507
|
/* Semantic */
|
|
@@ -577,8 +577,8 @@
|
|
|
577
577
|
|
|
578
578
|
/* Accent — slightly lighter than canonical purple for card contrast */
|
|
579
579
|
--wm-color-accent: #c9a7fa;
|
|
580
|
-
--wm-color-accent-hover: #
|
|
581
|
-
--wm-color-accent-text: #
|
|
580
|
+
--wm-color-accent-hover: #e5d5ff;
|
|
581
|
+
--wm-color-accent-text: #242632;
|
|
582
582
|
--wm-color-accent-readable: #dcc6fe;
|
|
583
583
|
|
|
584
584
|
/* Semantic */
|
|
@@ -657,8 +657,8 @@
|
|
|
657
657
|
|
|
658
658
|
/* Accent — warm peach */
|
|
659
659
|
--wm-color-accent: #f5986a;
|
|
660
|
-
--wm-color-accent-hover: #
|
|
661
|
-
--wm-color-accent-text: #
|
|
660
|
+
--wm-color-accent-hover: #ffc7ac;
|
|
661
|
+
--wm-color-accent-text: #0e0e1e;
|
|
662
662
|
--wm-color-accent-readable: #fead85;
|
|
663
663
|
|
|
664
664
|
/* Semantic */
|
|
@@ -737,7 +737,7 @@
|
|
|
737
737
|
|
|
738
738
|
/* Accent — thistle (muted lavender) */
|
|
739
739
|
--wm-color-accent: #c4a8d8;
|
|
740
|
-
--wm-color-accent-hover: #
|
|
740
|
+
--wm-color-accent-hover: #e7cafc;
|
|
741
741
|
--wm-color-accent-text: #1a1715;
|
|
742
742
|
--wm-color-accent-readable: #d8bced;
|
|
743
743
|
|
|
@@ -884,7 +884,7 @@
|
|
|
884
884
|
|
|
885
885
|
/* Accent — Monokai hot pink */
|
|
886
886
|
--wm-color-accent: #f92672;
|
|
887
|
-
--wm-color-accent-hover: #
|
|
887
|
+
--wm-color-accent-hover: #ff8dc2;
|
|
888
888
|
--wm-color-accent-text: #1c1c15;
|
|
889
889
|
/* #ff8ac4 was chosen for the WCAG failure (#f92672 is 2.9:1 on bg-float) and
|
|
890
890
|
cleared 5.03:1, but measures APCA Lc 51.4 there. See the note in :root. */
|
|
@@ -964,7 +964,7 @@
|
|
|
964
964
|
|
|
965
965
|
/* Accent — golden orange, the crepuscular ray color */
|
|
966
966
|
--wm-color-accent: #c09d06;
|
|
967
|
-
--wm-color-accent-hover: #
|
|
967
|
+
--wm-color-accent-hover: #e0bd3f;
|
|
968
968
|
--wm-color-accent-text: #060810;
|
|
969
969
|
--wm-color-accent-readable: #dcb83a;
|
|
970
970
|
|
|
@@ -1041,7 +1041,7 @@
|
|
|
1041
1041
|
|
|
1042
1042
|
/* Accent — medium green, needs dark text for contrast */
|
|
1043
1043
|
--wm-color-accent: #3fb950;
|
|
1044
|
-
--wm-color-accent-hover: #
|
|
1044
|
+
--wm-color-accent-hover: #62d96f;
|
|
1045
1045
|
--wm-color-accent-text: #0d1117;
|
|
1046
1046
|
--wm-color-accent-readable: #5dd46a;
|
|
1047
1047
|
|
|
@@ -1118,7 +1118,7 @@
|
|
|
1118
1118
|
|
|
1119
1119
|
/* Accent — Forest Moss Green */
|
|
1120
1120
|
--wm-color-accent: #82a682;
|
|
1121
|
-
--wm-color-accent-hover: #
|
|
1121
|
+
--wm-color-accent-hover: #9fc59f;
|
|
1122
1122
|
--wm-color-accent-text: #161817;
|
|
1123
1123
|
/* #9bc99b was chosen for the WCAG failure (#82a682 is 3.30:1 on bg-float) and
|
|
1124
1124
|
cleared 4.74:1, but measures APCA Lc 54.3 there. See the note in :root. */
|