@fragments-sdk/cli 0.7.16 → 0.7.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/cli",
3
- "version": "0.7.16",
3
+ "version": "0.7.17",
4
4
  "license": "FSL-1.1-MIT",
5
5
  "description": "CLI, MCP server, and dev tools for Fragments design system",
6
6
  "author": "Conan McNicholl",
@@ -10,7 +10,7 @@
10
10
  * No hardcoded hex values: everything flows from PALETTES + DEFAULT_SEEDS.
11
11
  */
12
12
 
13
- import { describe, it, expect } from 'vitest';
13
+ import { describe, it, expect } from "vitest";
14
14
  import {
15
15
  PALETTES,
16
16
  PALETTE_SEMANTIC_COLORS,
@@ -21,34 +21,29 @@ import {
21
21
  deriveSemanticText,
22
22
  deriveDarkAccent,
23
23
  hexToRgb,
24
- } from '@fragments/seed-derivation';
25
- import type { NeutralPalette } from '@fragments/seed-derivation';
26
- import {
27
- parseColor,
28
- contrastRatio,
29
- meetsAA,
30
- meetsAAA,
31
- } from '../contrast.js';
32
- import type { RGB } from '../contrast.js';
24
+ } from "@fragments/seed-derivation";
25
+ import type { NeutralPalette } from "@fragments/seed-derivation";
26
+ import { parseColor, contrastRatio, meetsAA, meetsAAA } from "../contrast.js";
27
+ import type { RGB } from "../contrast.js";
33
28
 
34
29
  // ── Fixed tokens (from libs/ui/src/tokens/_variables.scss, not seed-derived) ─
35
30
 
36
31
  const FIXED_TOKENS = {
37
- '--fui-tooltip-text': '$fui-tooltip-text',
38
- '--fui-tooltip-bg': '$fui-tooltip-bg',
39
- '--fui-code-text': '$fui-code-text',
40
- '--fui-code-text-muted': '$fui-code-text-muted',
41
- '--fui-code-bg': '$fui-code-bg',
32
+ "--fui-tooltip-text": "$fui-tooltip-text",
33
+ "--fui-tooltip-bg": "$fui-tooltip-bg",
34
+ "--fui-code-text": "$fui-code-text",
35
+ "--fui-code-text-muted": "$fui-code-text-muted",
36
+ "--fui-code-bg": "$fui-code-bg",
42
37
  } as const;
43
38
 
44
39
  // These SCSS defaults are not seed-derived — they're the same across all palettes.
45
40
  // Values sourced from libs/ui/src/tokens/_variables.scss lines 337-356.
46
41
  const SCSS_DEFAULTS: Record<(typeof FIXED_TOKENS)[keyof typeof FIXED_TOKENS], string> = {
47
- '$fui-tooltip-text': '#f8fafc',
48
- '$fui-tooltip-bg': '#1e293b',
49
- '$fui-code-text': '#d4d4d4',
50
- '$fui-code-text-muted': '#6b7280',
51
- '$fui-code-bg': '#1e1e1e',
42
+ "$fui-tooltip-text": "#f8fafc",
43
+ "$fui-tooltip-bg": "#1e293b",
44
+ "$fui-code-text": "#d4d4d4",
45
+ "$fui-code-text-muted": "#6b7280",
46
+ "$fui-code-bg": "#000000",
52
47
  };
53
48
 
54
49
  function fixedToken(varName: keyof typeof FIXED_TOKENS): string {
@@ -58,27 +53,27 @@ function fixedToken(varName: keyof typeof FIXED_TOKENS): string {
58
53
  // ── Token derivation (mirrors CSS custom property output) ────────────────────
59
54
 
60
55
  interface TokenMap {
61
- '--fui-text-primary': string;
62
- '--fui-text-secondary': string;
63
- '--fui-text-tertiary': string;
64
- '--fui-text-inverse': string;
65
- '--fui-bg-primary': string;
66
- '--fui-bg-secondary': string;
67
- '--fui-bg-tertiary': string;
68
- '--fui-bg-elevated': string;
69
- '--fui-color-accent': string;
70
- '--fui-color-danger': string;
71
- '--fui-color-success': string;
72
- '--fui-color-warning': string;
73
- '--fui-color-info': string;
74
- '--fui-color-danger-bg': string;
75
- '--fui-color-success-bg': string;
76
- '--fui-color-warning-bg': string;
77
- '--fui-color-info-bg': string;
78
- '--fui-color-danger-text': string;
79
- '--fui-color-success-text': string;
80
- '--fui-color-warning-text': string;
81
- '--fui-color-info-text': string;
56
+ "--fui-text-primary": string;
57
+ "--fui-text-secondary": string;
58
+ "--fui-text-tertiary": string;
59
+ "--fui-text-inverse": string;
60
+ "--fui-bg-primary": string;
61
+ "--fui-bg-secondary": string;
62
+ "--fui-bg-tertiary": string;
63
+ "--fui-bg-elevated": string;
64
+ "--fui-color-accent": string;
65
+ "--fui-color-danger": string;
66
+ "--fui-color-success": string;
67
+ "--fui-color-warning": string;
68
+ "--fui-color-info": string;
69
+ "--fui-color-danger-bg": string;
70
+ "--fui-color-success-bg": string;
71
+ "--fui-color-warning-bg": string;
72
+ "--fui-color-info-bg": string;
73
+ "--fui-color-danger-text": string;
74
+ "--fui-color-success-text": string;
75
+ "--fui-color-warning-text": string;
76
+ "--fui-color-info-text": string;
82
77
  }
83
78
 
84
79
  function deriveTokenMap(paletteName: NeutralPalette, brand: string, isDark: boolean): TokenMap {
@@ -89,27 +84,27 @@ function deriveTokenMap(paletteName: NeutralPalette, brand: string, isDark: bool
89
84
  const accent = isDark ? deriveDarkAccent(brand) : brand;
90
85
 
91
86
  return {
92
- '--fui-text-primary': text.primary,
93
- '--fui-text-secondary': text.secondary,
94
- '--fui-text-tertiary': text.tertiary,
95
- '--fui-text-inverse': text.inverse,
96
- '--fui-bg-primary': surfaces.primary,
97
- '--fui-bg-secondary': surfaces.secondary,
98
- '--fui-bg-tertiary': surfaces.tertiary,
99
- '--fui-bg-elevated': surfaces.elevated,
100
- '--fui-color-accent': accent,
101
- '--fui-color-danger': semantics.danger,
102
- '--fui-color-success': semantics.success,
103
- '--fui-color-warning': semantics.warning,
104
- '--fui-color-info': semantics.info,
105
- '--fui-color-danger-bg': deriveSemanticBg(semantics.danger, isDark),
106
- '--fui-color-success-bg': deriveSemanticBg(semantics.success, isDark),
107
- '--fui-color-warning-bg': deriveSemanticBg(semantics.warning, isDark),
108
- '--fui-color-info-bg': deriveSemanticBg(semantics.info, isDark),
109
- '--fui-color-danger-text': deriveSemanticText(semantics.danger, isDark),
110
- '--fui-color-success-text': deriveSemanticText(semantics.success, isDark),
111
- '--fui-color-warning-text': deriveSemanticText(semantics.warning, isDark),
112
- '--fui-color-info-text': deriveSemanticText(semantics.info, isDark),
87
+ "--fui-text-primary": text.primary,
88
+ "--fui-text-secondary": text.secondary,
89
+ "--fui-text-tertiary": text.tertiary,
90
+ "--fui-text-inverse": text.inverse,
91
+ "--fui-bg-primary": surfaces.primary,
92
+ "--fui-bg-secondary": surfaces.secondary,
93
+ "--fui-bg-tertiary": surfaces.tertiary,
94
+ "--fui-bg-elevated": surfaces.elevated,
95
+ "--fui-color-accent": accent,
96
+ "--fui-color-danger": semantics.danger,
97
+ "--fui-color-success": semantics.success,
98
+ "--fui-color-warning": semantics.warning,
99
+ "--fui-color-info": semantics.info,
100
+ "--fui-color-danger-bg": deriveSemanticBg(semantics.danger, isDark),
101
+ "--fui-color-success-bg": deriveSemanticBg(semantics.success, isDark),
102
+ "--fui-color-warning-bg": deriveSemanticBg(semantics.warning, isDark),
103
+ "--fui-color-info-bg": deriveSemanticBg(semantics.info, isDark),
104
+ "--fui-color-danger-text": deriveSemanticText(semantics.danger, isDark),
105
+ "--fui-color-success-text": deriveSemanticText(semantics.success, isDark),
106
+ "--fui-color-warning-text": deriveSemanticText(semantics.warning, isDark),
107
+ "--fui-color-info-text": deriveSemanticText(semantics.info, isDark),
113
108
  };
114
109
  }
115
110
 
@@ -138,7 +133,7 @@ function ratioOnComposite(fgHex: string, rgbaBg: string, baseHex: string): numbe
138
133
 
139
134
  // ── Tests ────────────────────────────────────────────────────────────────────
140
135
 
141
- const PALETTE_NAMES: NeutralPalette[] = ['stone', 'ice', 'earth', 'sand', 'fire'];
136
+ const PALETTE_NAMES: NeutralPalette[] = ["stone", "ice", "earth", "sand", "fire"];
142
137
  const brand = DEFAULT_SEEDS.brand;
143
138
 
144
139
  for (const paletteName of PALETTE_NAMES) {
@@ -146,193 +141,251 @@ for (const paletteName of PALETTE_NAMES) {
146
141
  const dark = deriveTokenMap(paletteName, brand, true);
147
142
 
148
143
  describe(`${paletteName} palette — Light Mode`, () => {
149
- describe('text hierarchy on --fui-bg-primary', () => {
150
- it('--fui-text-primary on --fui-bg-primary meets AA', () => {
151
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-primary']))).toBe(true);
144
+ describe("text hierarchy on --fui-bg-primary", () => {
145
+ it("--fui-text-primary on --fui-bg-primary meets AA", () => {
146
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-primary"]))).toBe(true);
152
147
  });
153
148
 
154
- it('--fui-text-secondary on --fui-bg-primary meets 3:1 (UI text minimum)', () => {
155
- expect(ratio(light['--fui-text-secondary'], light['--fui-bg-primary'])).toBeGreaterThanOrEqual(3.0);
149
+ it("--fui-text-secondary on --fui-bg-primary meets 3:1 (UI text minimum)", () => {
150
+ expect(
151
+ ratio(light["--fui-text-secondary"], light["--fui-bg-primary"])
152
+ ).toBeGreaterThanOrEqual(3.0);
156
153
  });
157
154
 
158
- it('--fui-text-tertiary on --fui-bg-primary has visible contrast', () => {
159
- expect(ratio(light['--fui-text-tertiary'], light['--fui-bg-primary'])).toBeGreaterThanOrEqual(1.0);
155
+ it("--fui-text-tertiary on --fui-bg-primary has visible contrast", () => {
156
+ expect(
157
+ ratio(light["--fui-text-tertiary"], light["--fui-bg-primary"])
158
+ ).toBeGreaterThanOrEqual(1.0);
160
159
  });
161
160
  });
162
161
 
163
- describe('text on alternate surfaces', () => {
164
- it('--fui-text-primary on --fui-bg-secondary meets AA', () => {
165
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-secondary']))).toBe(true);
162
+ describe("text on alternate surfaces", () => {
163
+ it("--fui-text-primary on --fui-bg-secondary meets AA", () => {
164
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-secondary"]))).toBe(true);
166
165
  });
167
166
 
168
- it('--fui-text-primary on --fui-bg-tertiary meets AA', () => {
169
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-tertiary']))).toBe(true);
167
+ it("--fui-text-primary on --fui-bg-tertiary meets AA", () => {
168
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-tertiary"]))).toBe(true);
170
169
  });
171
170
 
172
- it('--fui-text-primary on --fui-bg-elevated meets AA', () => {
173
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-elevated']))).toBe(true);
171
+ it("--fui-text-primary on --fui-bg-elevated meets AA", () => {
172
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-elevated"]))).toBe(true);
174
173
  });
175
174
 
176
- it('--fui-text-secondary on --fui-bg-elevated meets 3:1', () => {
177
- expect(ratio(light['--fui-text-secondary'], light['--fui-bg-elevated'])).toBeGreaterThanOrEqual(3.0);
175
+ it("--fui-text-secondary on --fui-bg-elevated meets 3:1", () => {
176
+ expect(
177
+ ratio(light["--fui-text-secondary"], light["--fui-bg-elevated"])
178
+ ).toBeGreaterThanOrEqual(3.0);
178
179
  });
179
180
  });
180
181
 
181
- describe('Button', () => {
182
- it('--fui-text-inverse on --fui-color-accent meets 3:1 (large text / bold buttons)', () => {
183
- expect(ratio(light['--fui-text-inverse'], light['--fui-color-accent'])).toBeGreaterThanOrEqual(3.0);
182
+ describe("Button", () => {
183
+ it("--fui-text-inverse on --fui-color-accent meets 3:1 (large text / bold buttons)", () => {
184
+ expect(
185
+ ratio(light["--fui-text-inverse"], light["--fui-color-accent"])
186
+ ).toBeGreaterThanOrEqual(3.0);
184
187
  });
185
188
 
186
- it('--fui-text-primary on --fui-bg-secondary (secondary button) meets AA', () => {
187
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-secondary']))).toBe(true);
189
+ it("--fui-text-primary on --fui-bg-secondary (secondary button) meets AA", () => {
190
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-secondary"]))).toBe(true);
188
191
  });
189
192
  });
190
193
 
191
- describe('Card', () => {
192
- it('--fui-text-primary on --fui-bg-elevated (title/body) meets AA', () => {
193
- expect(meetsAA(ratio(light['--fui-text-primary'], light['--fui-bg-elevated']))).toBe(true);
194
+ describe("Card", () => {
195
+ it("--fui-text-primary on --fui-bg-elevated (title/body) meets AA", () => {
196
+ expect(meetsAA(ratio(light["--fui-text-primary"], light["--fui-bg-elevated"]))).toBe(true);
194
197
  });
195
198
 
196
- it('--fui-text-secondary on --fui-bg-elevated (description) meets 3:1', () => {
197
- expect(ratio(light['--fui-text-secondary'], light['--fui-bg-elevated'])).toBeGreaterThanOrEqual(3.0);
199
+ it("--fui-text-secondary on --fui-bg-elevated (description) meets 3:1", () => {
200
+ expect(
201
+ ratio(light["--fui-text-secondary"], light["--fui-bg-elevated"])
202
+ ).toBeGreaterThanOrEqual(3.0);
198
203
  });
199
204
  });
200
205
 
201
- describe('semantic text on semantic bg (Badge, Alert)', () => {
202
- it('--fui-color-danger-text on composited --fui-color-danger-bg meets AA', () => {
203
- expect(ratioOnComposite(
204
- light['--fui-color-danger-text'], light['--fui-color-danger-bg'], light['--fui-bg-primary']
205
- )).toBeGreaterThanOrEqual(4.5);
206
+ describe("semantic text on semantic bg (Badge, Alert)", () => {
207
+ it("--fui-color-danger-text on composited --fui-color-danger-bg meets AA", () => {
208
+ expect(
209
+ ratioOnComposite(
210
+ light["--fui-color-danger-text"],
211
+ light["--fui-color-danger-bg"],
212
+ light["--fui-bg-primary"]
213
+ )
214
+ ).toBeGreaterThanOrEqual(4.5);
206
215
  });
207
216
 
208
- it('--fui-color-success-text on composited --fui-color-success-bg meets AA', () => {
209
- expect(ratioOnComposite(
210
- light['--fui-color-success-text'], light['--fui-color-success-bg'], light['--fui-bg-primary']
211
- )).toBeGreaterThanOrEqual(4.5);
217
+ it("--fui-color-success-text on composited --fui-color-success-bg meets AA", () => {
218
+ expect(
219
+ ratioOnComposite(
220
+ light["--fui-color-success-text"],
221
+ light["--fui-color-success-bg"],
222
+ light["--fui-bg-primary"]
223
+ )
224
+ ).toBeGreaterThanOrEqual(4.5);
212
225
  });
213
226
 
214
- it('--fui-color-warning-text on composited --fui-color-warning-bg meets AA', () => {
215
- expect(ratioOnComposite(
216
- light['--fui-color-warning-text'], light['--fui-color-warning-bg'], light['--fui-bg-primary']
217
- )).toBeGreaterThanOrEqual(4.5);
227
+ it("--fui-color-warning-text on composited --fui-color-warning-bg meets AA", () => {
228
+ expect(
229
+ ratioOnComposite(
230
+ light["--fui-color-warning-text"],
231
+ light["--fui-color-warning-bg"],
232
+ light["--fui-bg-primary"]
233
+ )
234
+ ).toBeGreaterThanOrEqual(4.5);
218
235
  });
219
236
 
220
- it('--fui-color-info-text on composited --fui-color-info-bg meets AA', () => {
221
- expect(ratioOnComposite(
222
- light['--fui-color-info-text'], light['--fui-color-info-bg'], light['--fui-bg-primary']
223
- )).toBeGreaterThanOrEqual(4.5);
237
+ it("--fui-color-info-text on composited --fui-color-info-bg meets AA", () => {
238
+ expect(
239
+ ratioOnComposite(
240
+ light["--fui-color-info-text"],
241
+ light["--fui-color-info-bg"],
242
+ light["--fui-bg-primary"]
243
+ )
244
+ ).toBeGreaterThanOrEqual(4.5);
224
245
  });
225
246
  });
226
247
  });
227
248
 
228
249
  describe(`${paletteName} palette — Dark Mode`, () => {
229
- describe('text hierarchy on --fui-bg-primary', () => {
230
- it('--fui-text-primary on --fui-bg-primary meets AA', () => {
231
- expect(meetsAA(ratio(dark['--fui-text-primary'], dark['--fui-bg-primary']))).toBe(true);
250
+ describe("text hierarchy on --fui-bg-primary", () => {
251
+ it("--fui-text-primary on --fui-bg-primary meets AA", () => {
252
+ expect(meetsAA(ratio(dark["--fui-text-primary"], dark["--fui-bg-primary"]))).toBe(true);
232
253
  });
233
254
 
234
- it('--fui-text-secondary on --fui-bg-primary meets 3:1', () => {
235
- expect(ratio(dark['--fui-text-secondary'], dark['--fui-bg-primary'])).toBeGreaterThanOrEqual(3.0);
255
+ it("--fui-text-secondary on --fui-bg-primary meets 3:1", () => {
256
+ expect(
257
+ ratio(dark["--fui-text-secondary"], dark["--fui-bg-primary"])
258
+ ).toBeGreaterThanOrEqual(3.0);
236
259
  });
237
260
 
238
- it('--fui-text-tertiary on --fui-bg-primary has visible contrast', () => {
239
- expect(ratio(dark['--fui-text-tertiary'], dark['--fui-bg-primary'])).toBeGreaterThanOrEqual(1.0);
261
+ it("--fui-text-tertiary on --fui-bg-primary has visible contrast", () => {
262
+ expect(ratio(dark["--fui-text-tertiary"], dark["--fui-bg-primary"])).toBeGreaterThanOrEqual(
263
+ 1.0
264
+ );
240
265
  });
241
266
  });
242
267
 
243
- describe('text on alternate surfaces', () => {
244
- it('--fui-text-primary on --fui-bg-secondary meets AA', () => {
245
- expect(meetsAA(ratio(dark['--fui-text-primary'], dark['--fui-bg-secondary']))).toBe(true);
268
+ describe("text on alternate surfaces", () => {
269
+ it("--fui-text-primary on --fui-bg-secondary meets AA", () => {
270
+ expect(meetsAA(ratio(dark["--fui-text-primary"], dark["--fui-bg-secondary"]))).toBe(true);
246
271
  });
247
272
 
248
- it('--fui-text-primary on --fui-bg-elevated meets AA', () => {
249
- expect(meetsAA(ratio(dark['--fui-text-primary'], dark['--fui-bg-elevated']))).toBe(true);
273
+ it("--fui-text-primary on --fui-bg-elevated meets AA", () => {
274
+ expect(meetsAA(ratio(dark["--fui-text-primary"], dark["--fui-bg-elevated"]))).toBe(true);
250
275
  });
251
276
  });
252
277
 
253
- describe('Button (dark)', () => {
254
- it('--fui-text-inverse on --fui-color-accent meets 3:1', () => {
255
- expect(ratio(dark['--fui-text-inverse'], dark['--fui-color-accent'])).toBeGreaterThanOrEqual(3.0);
278
+ describe("Button (dark)", () => {
279
+ it("--fui-text-inverse on --fui-color-accent meets 3:1", () => {
280
+ expect(
281
+ ratio(dark["--fui-text-inverse"], dark["--fui-color-accent"])
282
+ ).toBeGreaterThanOrEqual(3.0);
256
283
  });
257
284
  });
258
285
 
259
- describe('Card (dark)', () => {
260
- it('--fui-text-primary on --fui-bg-elevated meets AA', () => {
261
- expect(meetsAA(ratio(dark['--fui-text-primary'], dark['--fui-bg-elevated']))).toBe(true);
286
+ describe("Card (dark)", () => {
287
+ it("--fui-text-primary on --fui-bg-elevated meets AA", () => {
288
+ expect(meetsAA(ratio(dark["--fui-text-primary"], dark["--fui-bg-elevated"]))).toBe(true);
262
289
  });
263
290
 
264
- it('--fui-text-secondary on --fui-bg-elevated meets 3:1', () => {
265
- expect(ratio(dark['--fui-text-secondary'], dark['--fui-bg-elevated'])).toBeGreaterThanOrEqual(3.0);
291
+ it("--fui-text-secondary on --fui-bg-elevated meets 3:1", () => {
292
+ expect(
293
+ ratio(dark["--fui-text-secondary"], dark["--fui-bg-elevated"])
294
+ ).toBeGreaterThanOrEqual(3.0);
266
295
  });
267
296
  });
268
297
 
269
- describe('semantic text on semantic bg (dark)', () => {
270
- it('--fui-color-danger-text on composited --fui-color-danger-bg meets AA', () => {
271
- expect(ratioOnComposite(
272
- dark['--fui-color-danger-text'], dark['--fui-color-danger-bg'], dark['--fui-bg-primary']
273
- )).toBeGreaterThanOrEqual(4.5);
298
+ describe("semantic text on semantic bg (dark)", () => {
299
+ it("--fui-color-danger-text on composited --fui-color-danger-bg meets AA", () => {
300
+ expect(
301
+ ratioOnComposite(
302
+ dark["--fui-color-danger-text"],
303
+ dark["--fui-color-danger-bg"],
304
+ dark["--fui-bg-primary"]
305
+ )
306
+ ).toBeGreaterThanOrEqual(4.5);
274
307
  });
275
308
 
276
- it('--fui-color-success-text on composited --fui-color-success-bg meets AA', () => {
277
- expect(ratioOnComposite(
278
- dark['--fui-color-success-text'], dark['--fui-color-success-bg'], dark['--fui-bg-primary']
279
- )).toBeGreaterThanOrEqual(4.5);
309
+ it("--fui-color-success-text on composited --fui-color-success-bg meets AA", () => {
310
+ expect(
311
+ ratioOnComposite(
312
+ dark["--fui-color-success-text"],
313
+ dark["--fui-color-success-bg"],
314
+ dark["--fui-bg-primary"]
315
+ )
316
+ ).toBeGreaterThanOrEqual(4.5);
280
317
  });
281
318
 
282
- it('--fui-color-warning-text on composited --fui-color-warning-bg meets AA', () => {
283
- expect(ratioOnComposite(
284
- dark['--fui-color-warning-text'], dark['--fui-color-warning-bg'], dark['--fui-bg-primary']
285
- )).toBeGreaterThanOrEqual(4.5);
319
+ it("--fui-color-warning-text on composited --fui-color-warning-bg meets AA", () => {
320
+ expect(
321
+ ratioOnComposite(
322
+ dark["--fui-color-warning-text"],
323
+ dark["--fui-color-warning-bg"],
324
+ dark["--fui-bg-primary"]
325
+ )
326
+ ).toBeGreaterThanOrEqual(4.5);
286
327
  });
287
328
 
288
- it('--fui-color-info-text on composited --fui-color-info-bg meets AA', () => {
289
- expect(ratioOnComposite(
290
- dark['--fui-color-info-text'], dark['--fui-color-info-bg'], dark['--fui-bg-primary']
291
- )).toBeGreaterThanOrEqual(4.5);
329
+ it("--fui-color-info-text on composited --fui-color-info-bg meets AA", () => {
330
+ expect(
331
+ ratioOnComposite(
332
+ dark["--fui-color-info-text"],
333
+ dark["--fui-color-info-bg"],
334
+ dark["--fui-bg-primary"]
335
+ )
336
+ ).toBeGreaterThanOrEqual(4.5);
292
337
  });
293
338
  });
294
339
  });
295
340
  }
296
341
 
297
- describe('Cross-palette contrast report', () => {
342
+ describe("Cross-palette contrast report", () => {
298
343
  for (const paletteName of PALETTE_NAMES) {
299
344
  const light = deriveTokenMap(paletteName, brand, false);
300
345
  const dark = deriveTokenMap(paletteName, brand, true);
301
346
 
302
347
  it(`${paletteName} light — --fui-text-primary on --fui-bg-primary`, () => {
303
- const r = ratio(light['--fui-text-primary'], light['--fui-bg-primary']);
304
- console.log(` ${paletteName} light: ${light['--fui-text-primary']} on ${light['--fui-bg-primary']} = ${r.toFixed(2)}:1`);
348
+ const r = ratio(light["--fui-text-primary"], light["--fui-bg-primary"]);
349
+ console.log(
350
+ ` ${paletteName} light: ${light["--fui-text-primary"]} on ${light["--fui-bg-primary"]} = ${r.toFixed(2)}:1`
351
+ );
305
352
  expect(meetsAA(r)).toBe(true);
306
353
  });
307
354
 
308
355
  it(`${paletteName} dark — --fui-text-primary on --fui-bg-primary`, () => {
309
- const r = ratio(dark['--fui-text-primary'], dark['--fui-bg-primary']);
310
- console.log(` ${paletteName} dark: ${dark['--fui-text-primary']} on ${dark['--fui-bg-primary']} = ${r.toFixed(2)}:1`);
356
+ const r = ratio(dark["--fui-text-primary"], dark["--fui-bg-primary"]);
357
+ console.log(
358
+ ` ${paletteName} dark: ${dark["--fui-text-primary"]} on ${dark["--fui-bg-primary"]} = ${r.toFixed(2)}:1`
359
+ );
311
360
  expect(meetsAA(r)).toBe(true);
312
361
  });
313
362
 
314
363
  it(`${paletteName} light — --fui-text-inverse on --fui-color-accent`, () => {
315
- const r = ratio(light['--fui-text-inverse'], light['--fui-color-accent']);
364
+ const r = ratio(light["--fui-text-inverse"], light["--fui-color-accent"]);
316
365
  const aa = meetsAA(r);
317
366
  const aaLarge = meetsAA(r, true);
318
367
  console.log(
319
- ` ${paletteName}: ${light['--fui-text-inverse']} on ${light['--fui-color-accent']} = ${r.toFixed(2)}:1 — ${aa ? 'PASS AA' : aaLarge ? 'PASS large' : 'FAIL'}`
368
+ ` ${paletteName}: ${light["--fui-text-inverse"]} on ${light["--fui-color-accent"]} = ${r.toFixed(2)}:1 — ${aa ? "PASS AA" : aaLarge ? "PASS large" : "FAIL"}`
320
369
  );
321
370
  expect(r).toBeGreaterThanOrEqual(1.0);
322
371
  });
323
372
  }
324
373
  });
325
374
 
326
- describe('Fixed-token components', () => {
327
- it('--fui-tooltip-text on --fui-tooltip-bg meets AAA', () => {
328
- expect(meetsAAA(ratio(fixedToken('--fui-tooltip-text'), fixedToken('--fui-tooltip-bg')))).toBe(true);
375
+ describe("Fixed-token components", () => {
376
+ it("--fui-tooltip-text on --fui-tooltip-bg meets AAA", () => {
377
+ expect(meetsAAA(ratio(fixedToken("--fui-tooltip-text"), fixedToken("--fui-tooltip-bg")))).toBe(
378
+ true
379
+ );
329
380
  });
330
381
 
331
- it('--fui-code-text on --fui-code-bg meets AA', () => {
332
- expect(meetsAA(ratio(fixedToken('--fui-code-text'), fixedToken('--fui-code-bg')))).toBe(true);
382
+ it("--fui-code-text on --fui-code-bg meets AA", () => {
383
+ expect(meetsAA(ratio(fixedToken("--fui-code-text"), fixedToken("--fui-code-bg")))).toBe(true);
333
384
  });
334
385
 
335
- it('--fui-code-text-muted on --fui-code-bg meets 3:1', () => {
336
- expect(ratio(fixedToken('--fui-code-text-muted'), fixedToken('--fui-code-bg'))).toBeGreaterThanOrEqual(3.0);
386
+ it("--fui-code-text-muted on --fui-code-bg meets 3:1", () => {
387
+ expect(
388
+ ratio(fixedToken("--fui-code-text-muted"), fixedToken("--fui-code-bg"))
389
+ ).toBeGreaterThanOrEqual(3.0);
337
390
  });
338
391
  });