@wildmason/aegis 1.10.1 → 1.11.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.
Files changed (3) hide show
  1. package/inputs.css +14 -4
  2. package/package.json +4 -3
  3. package/themes.css +48 -1
package/inputs.css CHANGED
@@ -1129,15 +1129,25 @@ select.wm-input {
1129
1129
  color: var(--wm-text-primary);
1130
1130
  }
1131
1131
 
1132
+ /* Fill and edge come from separate tokens, and the split is the whole point.
1133
+ *
1134
+ * `--wm-color-danger` is tuned for danger as TEXT, so on dark themes it is a
1135
+ * light red and white on it failed WCAG AA on 8 of 12 themes (worst 2.74:1).
1136
+ * `--wm-color-danger-solid` is dark enough for the label on every theme;
1137
+ * `--wm-color-danger-edge` supplies the 3:1 component boundary WCAG 1.4.11
1138
+ * asks for, which a fill dark enough for white text cannot always provide by
1139
+ * itself — on arctic-night the two constraints cross outright. See themes.css
1140
+ * for the derivation and the APCA/WCAG divergence behind it. */
1132
1141
  .wm-btn--destructive {
1133
- background-color: var(--wm-color-danger);
1134
- border-color: var(--wm-color-danger);
1142
+ background-color: var(--wm-color-danger-solid);
1143
+ border-color: var(--wm-color-danger-edge);
1135
1144
  color: #ffffff;
1136
1145
  }
1137
1146
 
1147
+ /* Only the fill darkens on hover. Darkening the edge too would eat into the
1148
+ * boundary contrast the edge exists to guarantee. */
1138
1149
  .wm-btn--destructive:hover:not(:disabled) {
1139
- background-color: color-mix(in srgb, var(--wm-color-danger) 85%, black);
1140
- border-color: color-mix(in srgb, var(--wm-color-danger) 85%, black);
1150
+ background-color: color-mix(in srgb, var(--wm-color-danger-solid) 85%, black);
1141
1151
  }
1142
1152
 
1143
1153
  .wm-btn--flat {
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@wildmason/aegis",
3
- "version": "1.10.1",
3
+ "version": "1.11.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 && ng-packagr -p ng-package.json",
8
- "prepublishOnly": "npm run build"
7
+ "build": "npm run check:offline-fonts && npm run check:destructive-contrast && ng-packagr -p ng-package.json",
8
+ "prepublishOnly": "npm run build",
9
+ "check:destructive-contrast": "node scripts/check-destructive-contrast.mjs"
9
10
  },
10
11
  "files": [
11
12
  "dist",
package/themes.css CHANGED
@@ -40,6 +40,15 @@
40
40
  - Large text and UI components: 3.0:1 minimum
41
41
  (WCAG 1.4.11 Non-text Contrast — applies to --wm-border-input)
42
42
 
43
+ One pair needed a second token to hold that line: white on
44
+ --wm-color-danger, the destructive button's fill, failed AA on 8 of the 12
45
+ themes because --wm-color-danger is tuned for danger as TEXT and is a light
46
+ red on dark themes. The fill now comes from --wm-color-danger-solid and the
47
+ component boundary from --wm-color-danger-edge. Worth knowing if you are
48
+ auditing: APCA passed 11 of those 12 (Lc >= 60) — WCAG 2.x under-rates red
49
+ backgrounds — so the two models genuinely disagreed here and both bars are
50
+ now cleared rather than one being argued away.
51
+
43
52
  Placeholder text (--wm-text-placeholder) is intentionally lower contrast.
44
53
  WCAG 2.2 Understanding 1.4.3 explicitly exempts placeholder text from
45
54
  contrast requirements. Inputs MUST have a visible label; placeholder is
@@ -90,7 +99,7 @@
90
99
  --wm-transition-slow: 300ms ease;
91
100
 
92
101
  /* Typography */
93
- --wm-font-sans: system-ui, -apple-system, 'Segoe UI', sans-serif;
102
+ --wm-font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
94
103
  --wm-font-mono:
95
104
  'Cascadia Code', 'Fira Code', Consolas, 'Courier New', monospace;
96
105
 
@@ -131,6 +140,36 @@
131
140
 
132
141
  /* Derived tokens — computed at scope, valid for all themes */
133
142
  --wm-bg-active: color-mix(in srgb, var(--wm-color-accent) 10%, transparent);
143
+ /* Destructive-button fill and edge.
144
+ *
145
+ * `--wm-color-danger` is tuned for danger as TEXT on the theme's own
146
+ * background, so on dark themes it is a light red. White on it fails WCAG AA
147
+ * on 8 of the 12 themes — worst 2.74:1 on twilight-peach — even though APCA
148
+ * passes 11 of 12 (Lc >= 60). That divergence is real, not a rounding
149
+ * argument: WCAG 2.x's luminance formula under-rates red backgrounds. Both
150
+ * bars have to clear, so the fill gets its own token.
151
+ *
152
+ * Themes whose danger is already dark enough inherit it unchanged; the rest
153
+ * override below with a darkened value chosen so white clears 4.5:1 AND
154
+ * Lc 60, hover included.
155
+ */
156
+ --wm-color-danger-solid: var(--wm-color-danger);
157
+
158
+ /* The button's boundary, per WCAG 1.4.11's 3:1 for a component edge.
159
+ *
160
+ * Derived from the theme's own text colour rather than a fixed lightening:
161
+ * text-primary is by construction the highest-contrast colour against that
162
+ * theme's surfaces, so mixing toward it lightens on dark themes and darkens
163
+ * on light ones — one rule, correct in both directions, and a new theme gets
164
+ * a correct edge for free. 70/30 is the first ratio that clears 3:1 on all
165
+ * twelve themes against BOTH `--wm-bg-base` and `--wm-bg-float`; a dialog's
166
+ * raised surface is the harder case and is what 85/15 failed.
167
+ */
168
+ --wm-color-danger-edge: color-mix(
169
+ in srgb,
170
+ var(--wm-color-danger) 70%,
171
+ var(--wm-text-primary)
172
+ );
134
173
  --wm-color-danger-bg: color-mix(
135
174
  in srgb,
136
175
  var(--wm-color-danger) 8%,
@@ -347,6 +386,7 @@
347
386
  --wm-color-success: #b5cf9a;
348
387
  --wm-color-warning: #ebcb8b;
349
388
  --wm-color-danger: #bf616a;
389
+ --wm-color-danger-solid: #a34049;
350
390
 
351
391
  /* Item type colors */
352
392
  --wm-color-task: #88c0d0;
@@ -419,6 +459,7 @@
419
459
  --wm-color-success: #50fa7b;
420
460
  --wm-color-warning: #f1fa8c;
421
461
  --wm-color-danger: #ff5555;
462
+ --wm-color-danger-solid: #cf4545;
422
463
 
423
464
  /* Item type colors */
424
465
  --wm-color-task: #8be9fd;
@@ -491,6 +532,7 @@
491
532
  --wm-color-success: #5cbfa0;
492
533
  --wm-color-warning: #f0b464;
493
534
  --wm-color-danger: #f07878;
535
+ --wm-color-danger-solid: #b65b5b;
494
536
 
495
537
  /* Item type colors */
496
538
  --wm-color-task: #70a8f0;
@@ -563,6 +605,7 @@
563
605
  --wm-color-success: #7ac4a0;
564
606
  --wm-color-warning: #d4a85a;
565
607
  --wm-color-danger: #e07878;
608
+ --wm-color-danger-solid: #af5e5e;
566
609
 
567
610
  /* Item type colors */
568
611
  --wm-color-task: #80a8e0;
@@ -708,6 +751,7 @@
708
751
  --wm-color-success: #a6e22e;
709
752
  --wm-color-warning: #fd971f;
710
753
  --wm-color-danger: #f92672;
754
+ --wm-color-danger-solid: #e02267;
711
755
 
712
756
  /* Item type colors */
713
757
  --wm-color-task: #66d9ef;
@@ -780,6 +824,7 @@
780
824
  --wm-color-success: #4aba80;
781
825
  --wm-color-warning: #d4830a;
782
826
  --wm-color-danger: #e05c5c;
827
+ --wm-color-danger-solid: #c35050;
783
828
 
784
829
  /* Item type colors */
785
830
  --wm-color-task: #8ab4d8;
@@ -852,6 +897,7 @@
852
897
  --wm-color-success: #3fb950;
853
898
  --wm-color-warning: #d29922;
854
899
  --wm-color-danger: #f85149;
900
+ --wm-color-danger-solid: #d0443d;
855
901
 
856
902
  /* Item type colors */
857
903
  --wm-color-task: #58a6ff;
@@ -930,6 +976,7 @@
930
976
  --wm-color-success: #a0c5a0;
931
977
  --wm-color-warning: #ebcb8b;
932
978
  --wm-color-danger: #bf616a;
979
+ --wm-color-danger-solid: #b45b64;
933
980
 
934
981
  /* Item type colors — Wildmason selection */
935
982
  --wm-color-task: #82a682;