@conductor-by-89soone/tokens 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +280 -15
- package/dist/contrast-cli.js +440 -17
- package/dist/contrast-report.json +2397 -341
- package/dist/index.d.ts +40 -1
- package/dist/index.js +65 -3
- package/dist/lint-cli.js +15 -5
- package/dist/tokens.css +115 -4
- package/dist/tokens.d.ts +45 -0
- package/dist/tokens.js +47 -2
- package/dist/tokens.json +396 -7
- package/package.json +1 -1
package/dist/contrast-cli.js
CHANGED
|
@@ -26,6 +26,8 @@ var EXIT_CODES = {
|
|
|
26
26
|
"TOK-CP-USAGE": 1,
|
|
27
27
|
"TOK-CP-COLOR": 1,
|
|
28
28
|
"TOK-CP-ALPHA": 1,
|
|
29
|
+
"TOK-CP-FORBIDDEN": 1,
|
|
30
|
+
"TOK-THEME-KEY": 1,
|
|
29
31
|
"TOK-LITERAL": 1,
|
|
30
32
|
"TOK-ARG": 3
|
|
31
33
|
};
|
|
@@ -270,12 +272,96 @@ var badgePairs = [
|
|
|
270
272
|
"badge.marker.background",
|
|
271
273
|
"nonText",
|
|
272
274
|
"tokens spec 8.2 names the foreground `badge.marker.dot`; that key is a variant slot rather than a token, and it resolves to `status.queued` for the only declared variant."
|
|
275
|
+
),
|
|
276
|
+
pair(
|
|
277
|
+
"CP-042",
|
|
278
|
+
"status.neutralEnd",
|
|
279
|
+
"badge.marker.background",
|
|
280
|
+
"nonText",
|
|
281
|
+
"CR-035. The second marker variant, measurable again now that the dark end state is `slate.400`. New id: CP-025 is permanently retired (tokens spec 8.2, 8.5)."
|
|
273
282
|
)
|
|
274
283
|
];
|
|
275
284
|
var disabledPairs = [
|
|
276
285
|
pair("CP-040", "text.muted", "state.disabled", "body"),
|
|
277
286
|
pair("CP-041", "button.policyDisabled.text", "state.disabledPolicy", "body")
|
|
278
287
|
];
|
|
288
|
+
var datavizPairs = [
|
|
289
|
+
pair("CP-043", "dataviz.series.1", "surface.base", "nonText"),
|
|
290
|
+
pair("CP-044", "dataviz.series.1", "surface.canvas", "nonText"),
|
|
291
|
+
pair("CP-045", "dataviz.series.1", "surface.raised", "nonText"),
|
|
292
|
+
pair("CP-046", "dataviz.series.2", "surface.base", "nonText"),
|
|
293
|
+
pair("CP-047", "dataviz.series.2", "surface.canvas", "nonText"),
|
|
294
|
+
pair("CP-048", "dataviz.series.2", "surface.raised", "nonText"),
|
|
295
|
+
pair("CP-049", "dataviz.series.3", "surface.base", "nonText"),
|
|
296
|
+
pair("CP-050", "dataviz.series.3", "surface.canvas", "nonText"),
|
|
297
|
+
pair("CP-051", "dataviz.series.3", "surface.raised", "nonText"),
|
|
298
|
+
pair("CP-052", "dataviz.series.4", "surface.base", "nonText"),
|
|
299
|
+
pair("CP-053", "dataviz.series.4", "surface.canvas", "nonText"),
|
|
300
|
+
pair("CP-054", "dataviz.series.4", "surface.raised", "nonText"),
|
|
301
|
+
pair("CP-055", "dataviz.series.5", "surface.base", "nonText"),
|
|
302
|
+
pair("CP-056", "dataviz.series.5", "surface.canvas", "nonText"),
|
|
303
|
+
pair("CP-057", "dataviz.series.5", "surface.raised", "nonText"),
|
|
304
|
+
pair("CP-058", "dataviz.series.6", "surface.base", "nonText"),
|
|
305
|
+
pair("CP-059", "dataviz.series.6", "surface.canvas", "nonText"),
|
|
306
|
+
pair("CP-060", "dataviz.series.6", "surface.raised", "nonText"),
|
|
307
|
+
pair("CP-061", "dataviz.series.7", "surface.base", "nonText"),
|
|
308
|
+
pair("CP-062", "dataviz.series.7", "surface.canvas", "nonText"),
|
|
309
|
+
pair("CP-063", "dataviz.series.7", "surface.raised", "nonText"),
|
|
310
|
+
pair("CP-064", "dataviz.series.8", "surface.base", "nonText"),
|
|
311
|
+
pair("CP-065", "dataviz.series.8", "surface.canvas", "nonText"),
|
|
312
|
+
pair("CP-066", "dataviz.series.8", "surface.raised", "nonText"),
|
|
313
|
+
pair("CP-067", "dataviz.series.9", "surface.base", "nonText"),
|
|
314
|
+
pair("CP-068", "dataviz.series.9", "surface.canvas", "nonText"),
|
|
315
|
+
pair("CP-069", "dataviz.series.9", "surface.raised", "nonText"),
|
|
316
|
+
pair("CP-070", "dataviz.series.10", "surface.base", "nonText"),
|
|
317
|
+
pair("CP-071", "dataviz.series.10", "surface.canvas", "nonText"),
|
|
318
|
+
pair("CP-072", "dataviz.series.10", "surface.raised", "nonText"),
|
|
319
|
+
pair("CP-073", "dataviz.series.11", "surface.base", "nonText"),
|
|
320
|
+
pair("CP-074", "dataviz.series.11", "surface.canvas", "nonText"),
|
|
321
|
+
pair("CP-075", "dataviz.series.11", "surface.raised", "nonText"),
|
|
322
|
+
pair("CP-076", "dataviz.series.12", "surface.base", "nonText"),
|
|
323
|
+
pair("CP-077", "dataviz.series.12", "surface.canvas", "nonText"),
|
|
324
|
+
pair("CP-078", "dataviz.series.12", "surface.raised", "nonText"),
|
|
325
|
+
pair("CP-079", "dataviz.series.13", "surface.base", "nonText"),
|
|
326
|
+
pair("CP-080", "dataviz.series.13", "surface.canvas", "nonText"),
|
|
327
|
+
pair("CP-081", "dataviz.series.13", "surface.raised", "nonText"),
|
|
328
|
+
pair("CP-082", "dataviz.series.14", "surface.base", "nonText"),
|
|
329
|
+
pair("CP-083", "dataviz.series.14", "surface.canvas", "nonText"),
|
|
330
|
+
pair("CP-084", "dataviz.series.14", "surface.raised", "nonText"),
|
|
331
|
+
pair("CP-085", "dataviz.series.15", "surface.base", "nonText"),
|
|
332
|
+
pair("CP-086", "dataviz.series.15", "surface.canvas", "nonText"),
|
|
333
|
+
pair("CP-087", "dataviz.series.15", "surface.raised", "nonText"),
|
|
334
|
+
pair("CP-088", "dataviz.series.16", "surface.base", "nonText"),
|
|
335
|
+
pair("CP-089", "dataviz.series.16", "surface.canvas", "nonText"),
|
|
336
|
+
pair("CP-090", "dataviz.series.16", "surface.raised", "nonText"),
|
|
337
|
+
pair("CP-091", "dataviz.series.17", "surface.base", "nonText"),
|
|
338
|
+
pair("CP-092", "dataviz.series.17", "surface.canvas", "nonText"),
|
|
339
|
+
pair("CP-093", "dataviz.series.17", "surface.raised", "nonText"),
|
|
340
|
+
pair("CP-094", "dataviz.series.18", "surface.base", "nonText"),
|
|
341
|
+
pair("CP-095", "dataviz.series.18", "surface.canvas", "nonText"),
|
|
342
|
+
pair("CP-096", "dataviz.series.18", "surface.raised", "nonText"),
|
|
343
|
+
pair("CP-097", "dataviz.series.19", "surface.base", "nonText"),
|
|
344
|
+
pair("CP-098", "dataviz.series.19", "surface.canvas", "nonText"),
|
|
345
|
+
pair("CP-099", "dataviz.series.19", "surface.raised", "nonText"),
|
|
346
|
+
pair("CP-100", "dataviz.series.20", "surface.base", "nonText"),
|
|
347
|
+
pair("CP-101", "dataviz.series.20", "surface.canvas", "nonText"),
|
|
348
|
+
pair("CP-102", "dataviz.series.20", "surface.raised", "nonText"),
|
|
349
|
+
pair("CP-103", "dataviz.sequential.1", "surface.base", "nonText"),
|
|
350
|
+
pair("CP-104", "dataviz.sequential.1", "surface.canvas", "nonText"),
|
|
351
|
+
pair("CP-105", "dataviz.sequential.1", "surface.raised", "nonText"),
|
|
352
|
+
pair("CP-106", "dataviz.sequential.2", "surface.base", "nonText"),
|
|
353
|
+
pair("CP-107", "dataviz.sequential.2", "surface.canvas", "nonText"),
|
|
354
|
+
pair("CP-108", "dataviz.sequential.2", "surface.raised", "nonText"),
|
|
355
|
+
pair("CP-109", "dataviz.sequential.3", "surface.base", "nonText"),
|
|
356
|
+
pair("CP-110", "dataviz.sequential.3", "surface.canvas", "nonText"),
|
|
357
|
+
pair("CP-111", "dataviz.sequential.3", "surface.raised", "nonText"),
|
|
358
|
+
pair("CP-112", "dataviz.sequential.4", "surface.base", "nonText"),
|
|
359
|
+
pair("CP-113", "dataviz.sequential.4", "surface.canvas", "nonText"),
|
|
360
|
+
pair("CP-114", "dataviz.sequential.4", "surface.raised", "nonText"),
|
|
361
|
+
pair("CP-115", "dataviz.sequential.5", "surface.base", "nonText"),
|
|
362
|
+
pair("CP-116", "dataviz.sequential.5", "surface.canvas", "nonText"),
|
|
363
|
+
pair("CP-117", "dataviz.sequential.5", "surface.raised", "nonText")
|
|
364
|
+
];
|
|
279
365
|
var contrastPairs = [
|
|
280
366
|
...textOnSurface,
|
|
281
367
|
...accentPairs,
|
|
@@ -284,7 +370,25 @@ var contrastPairs = [
|
|
|
284
370
|
...meterPairs,
|
|
285
371
|
...severityPairs,
|
|
286
372
|
...badgePairs,
|
|
287
|
-
...disabledPairs
|
|
373
|
+
...disabledPairs,
|
|
374
|
+
...datavizPairs
|
|
375
|
+
];
|
|
376
|
+
var forbiddenPairs = [
|
|
377
|
+
{
|
|
378
|
+
id: "FP-001",
|
|
379
|
+
foreground: "text.faint",
|
|
380
|
+
background: "surface.elevated",
|
|
381
|
+
reason: "`text.faint` is `decorative` and may not be painted on this surface \u2014 2.94:1 in dark, still short of body 4.5:1 in light (FR-THM-005 AC-3)"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: "FP-002",
|
|
385
|
+
foreground: "accent",
|
|
386
|
+
background: "surface.elevated",
|
|
387
|
+
reason: "the accent is a body foreground on `surface.base` and `surface.raised` only; on the elevated surface it measures 4.40:1 in dark, below body 4.5:1 (tokens spec 8.4)",
|
|
388
|
+
// Body only. 4.40:1 clears both the `large` 3:1 and the `nonText` 3:1 thresholds, and the
|
|
389
|
+
// SRS forbids only body use on this surface.
|
|
390
|
+
usages: ["body"]
|
|
391
|
+
}
|
|
288
392
|
];
|
|
289
393
|
|
|
290
394
|
// src/scales.ts
|
|
@@ -347,6 +451,11 @@ var radius = [
|
|
|
347
451
|
aliased("radius.xl", "curve.24", "Largest radius."),
|
|
348
452
|
semantic("radius.pill", "9999px", "Fully rounded badge, toggle, marker and progress geometry.")
|
|
349
453
|
];
|
|
454
|
+
var borderWidth = [
|
|
455
|
+
aliased("border.width.hairline", "stroke.1", "\uAE30\uBCF8 1px \uC5E3\uC9C0."),
|
|
456
|
+
aliased("border.width.emphasis", "stroke.2", "\uD45C \uD5E4\uB354 \uADDC\uCE59, \uB9C8\uCEE4 \uB9C1."),
|
|
457
|
+
aliased("border.width.rail", "stroke.3", "\uBC30\uB108 \uC0C1\uD0DC \uB808\uC77C, \uB0B4\uBE44 \uD65C\uC131 \uC778\uB514\uCF00\uC774\uD130.")
|
|
458
|
+
];
|
|
350
459
|
var Z_LAYERS = {
|
|
351
460
|
base: 0,
|
|
352
461
|
raised: 10,
|
|
@@ -389,6 +498,7 @@ var scaleTokens = [
|
|
|
389
498
|
...fontLineHeight,
|
|
390
499
|
...space,
|
|
391
500
|
...radius,
|
|
501
|
+
...borderWidth,
|
|
392
502
|
...z,
|
|
393
503
|
...breakpoint,
|
|
394
504
|
...motion
|
|
@@ -472,14 +582,14 @@ var badge = [
|
|
|
472
582
|
component("badge.marker.border", ref("border.strong"), "Marker-shape edge."),
|
|
473
583
|
component("badge.marker.dotSize", value("9px"), "Status dot diameter."),
|
|
474
584
|
component("badge.marker.dotRing", ref("surface.raised"), "Marker dot ring."),
|
|
475
|
-
component("badge.marker.dotRingWidth",
|
|
585
|
+
component("badge.marker.dotRingWidth", ref("border.width.emphasis"), "Marker dot ring width."),
|
|
476
586
|
component("badge.severity.text", ref("text.primary"), "Label on a severity fill. 4.67:1 to 9.32:1.", "body")
|
|
477
587
|
];
|
|
478
588
|
var table = [
|
|
479
589
|
component("table.headerText", ref("text.muted"), "Column header text.", "body"),
|
|
480
590
|
component("table.headerFontSize", ref("font.size.base"), "Column header size."),
|
|
481
591
|
component("table.headerBorder", ref("border.default"), "Header rule."),
|
|
482
|
-
component("table.headerBorderWidth",
|
|
592
|
+
component("table.headerBorderWidth", ref("border.width.emphasis"), "Header rule width."),
|
|
483
593
|
component(
|
|
484
594
|
"table.cellBorder",
|
|
485
595
|
ref("border.default"),
|
|
@@ -591,6 +701,9 @@ var overlay = [
|
|
|
591
701
|
];
|
|
592
702
|
var HEADING_MIN_PX = FONT_SIZE_PX.xl * 1.2;
|
|
593
703
|
var HEADING_MAX_PX = FONT_SIZE_PX.xl * 1.6;
|
|
704
|
+
var H2_PX = Math.round(FONT_SIZE_PX.xl * 1.3);
|
|
705
|
+
var H3_PX = Math.round(FONT_SIZE_PX.xl * 1.1);
|
|
706
|
+
var HEADING_LINE_HEIGHT_RATIO = 1.3;
|
|
594
707
|
var page = [
|
|
595
708
|
component(
|
|
596
709
|
"page.headingSize",
|
|
@@ -602,6 +715,26 @@ var page = [
|
|
|
602
715
|
value("1.16"),
|
|
603
716
|
"The only unitless line height: `clamp()` makes a px value impossible here."
|
|
604
717
|
),
|
|
718
|
+
component(
|
|
719
|
+
"page.sectionHeadingSize",
|
|
720
|
+
value(`${H2_PX}px`),
|
|
721
|
+
"`h2`. `font.size.xl` \xD7 1.3."
|
|
722
|
+
),
|
|
723
|
+
component(
|
|
724
|
+
"page.sectionHeadingLineHeight",
|
|
725
|
+
value(`${roundHalfUp(H2_PX * HEADING_LINE_HEIGHT_RATIO)}px`),
|
|
726
|
+
"Line height paired with `page.sectionHeadingSize`, at the 1.30 heading ratio."
|
|
727
|
+
),
|
|
728
|
+
component(
|
|
729
|
+
"page.subHeadingSize",
|
|
730
|
+
value(`${H3_PX}px`),
|
|
731
|
+
"`h3`. `font.size.xl` \xD7 1.1."
|
|
732
|
+
),
|
|
733
|
+
component(
|
|
734
|
+
"page.subHeadingLineHeight",
|
|
735
|
+
value(`${roundHalfUp(H3_PX * HEADING_LINE_HEIGHT_RATIO)}px`),
|
|
736
|
+
"Line height paired with `page.subHeadingSize`, at the 1.30 heading ratio."
|
|
737
|
+
),
|
|
605
738
|
component("page.stackGap", ref("space.6"), "Gap between page sections."),
|
|
606
739
|
component("page.stackGapCompact", ref("space.5"), "Section gap below `breakpoint.sm`."),
|
|
607
740
|
component("page.contentStackGap", ref("space.5"), "Gap inside a content stack."),
|
|
@@ -614,12 +747,21 @@ var page = [
|
|
|
614
747
|
component("page.skipLinkZ", ref("z.popover"), "Skip link stacking layer.")
|
|
615
748
|
];
|
|
616
749
|
var shell = [
|
|
750
|
+
component(
|
|
751
|
+
"appShell.background",
|
|
752
|
+
value("radial-gradient(circle at 82% -10%, {surface.tint.1}, transparent 34rem), radial-gradient(circle at 10% 85%, {surface.tint.2}, transparent 30rem), {surface.base}"),
|
|
753
|
+
"Ambient app-shell surface derived from the source application background."
|
|
754
|
+
),
|
|
617
755
|
component("appShell.navWidth", ref("page.shellNavWidth"), "AppShell desktop navigation width."),
|
|
618
756
|
component("appShell.mainMaxWidth", value("1480px"), "AppShell main content maximum width."),
|
|
619
757
|
component("appShell.overlayBackground", ref("surface.overlay"), "Mobile navigation scrim."),
|
|
620
758
|
component("skipLink.background", ref("accent.DEFAULT"), "Skip-link fill."),
|
|
621
759
|
component("skipLink.text", ref("text.inverse"), "Skip-link label."),
|
|
622
|
-
component(
|
|
760
|
+
component(
|
|
761
|
+
"navList.background",
|
|
762
|
+
value("linear-gradient(180deg, {surface.glass}, {surface.canvas})"),
|
|
763
|
+
"Glass navigation surface over the app-shell ambient background."
|
|
764
|
+
),
|
|
623
765
|
component("navList.border", ref("border.subtle"), "Navigation surface edge."),
|
|
624
766
|
component("navItem.text", ref("text.muted"), "Navigation item label."),
|
|
625
767
|
component("navItem.textActive", ref("text.primary"), "Active navigation item label."),
|
|
@@ -717,6 +859,18 @@ var surface = [
|
|
|
717
859
|
usage: "decorative",
|
|
718
860
|
value: "rgba(255, 255, 255, 0.05)",
|
|
719
861
|
description: "Progress and meter track, matching the source 1:1."
|
|
862
|
+
}),
|
|
863
|
+
darkToken({
|
|
864
|
+
key: "surface.tint.1",
|
|
865
|
+
usage: "decorative",
|
|
866
|
+
value: "rgba(109, 124, 255, 0.11)",
|
|
867
|
+
description: "Primary ambient glow from the source application background. Decorative only."
|
|
868
|
+
}),
|
|
869
|
+
darkToken({
|
|
870
|
+
key: "surface.tint.2",
|
|
871
|
+
usage: "decorative",
|
|
872
|
+
value: "rgba(20, 184, 166, 0.055)",
|
|
873
|
+
description: "Secondary ambient glow from the source application background. Decorative only."
|
|
720
874
|
})
|
|
721
875
|
];
|
|
722
876
|
var text = [
|
|
@@ -860,10 +1014,10 @@ var status = [
|
|
|
860
1014
|
}),
|
|
861
1015
|
darkToken({
|
|
862
1016
|
key: "status.neutralEnd",
|
|
863
|
-
usage: "
|
|
864
|
-
value: "#
|
|
1017
|
+
usage: "nonText",
|
|
1018
|
+
value: "#94a3b8",
|
|
865
1019
|
icon: "circle-slash",
|
|
866
|
-
description: "Cancelled or superseded.
|
|
1020
|
+
description: "Cancelled or superseded. `slate.400` at 6.61:1 on `surface.raised` (CP-042). The marker is drawn as a ring rather than a fill, so it stays distinguishable from queued's filled dot by shape as well as colour. CR-035 retires the CR-006 contrast exemption at this value: the old `#475569` measured 2.04:1 to 2.60:1 and could only be classified `decorative`, which meant the end-state dot read faintly against every dark surface."
|
|
867
1021
|
})
|
|
868
1022
|
];
|
|
869
1023
|
var meter = [
|
|
@@ -982,6 +1136,158 @@ var interaction = [
|
|
|
982
1136
|
description: "Policy-blocked fill. Contrast-exempt as a fill; checked beneath the label (5.27:1)."
|
|
983
1137
|
})
|
|
984
1138
|
];
|
|
1139
|
+
var dataviz = [
|
|
1140
|
+
darkToken({
|
|
1141
|
+
key: "dataviz.series.1",
|
|
1142
|
+
usage: "nonText",
|
|
1143
|
+
value: "#e88171",
|
|
1144
|
+
description: "Categorical chart series 1 of 20. Fill only; non-text 3:1 on chart surfaces (CP-043~CP-045). Series identity only; carries no magnitude."
|
|
1145
|
+
}),
|
|
1146
|
+
darkToken({
|
|
1147
|
+
key: "dataviz.series.2",
|
|
1148
|
+
usage: "nonText",
|
|
1149
|
+
value: "#1db198",
|
|
1150
|
+
description: "Categorical chart series 2 of 20. Fill only; non-text 3:1 on chart surfaces (CP-046~CP-048). Series identity only; carries no magnitude."
|
|
1151
|
+
}),
|
|
1152
|
+
darkToken({
|
|
1153
|
+
key: "dataviz.series.3",
|
|
1154
|
+
usage: "nonText",
|
|
1155
|
+
value: "#e979ad",
|
|
1156
|
+
description: "Categorical chart series 3 of 20. Fill only; non-text 3:1 on chart surfaces (CP-049~CP-051). Series identity only; carries no magnitude."
|
|
1157
|
+
}),
|
|
1158
|
+
darkToken({
|
|
1159
|
+
key: "dataviz.series.4",
|
|
1160
|
+
usage: "nonText",
|
|
1161
|
+
value: "#1eb641",
|
|
1162
|
+
description: "Categorical chart series 4 of 20. Fill only; non-text 3:1 on chart surfaces (CP-052~CP-054). Series identity only; carries no magnitude."
|
|
1163
|
+
}),
|
|
1164
|
+
darkToken({
|
|
1165
|
+
key: "dataviz.series.5",
|
|
1166
|
+
usage: "nonText",
|
|
1167
|
+
value: "#e073e8",
|
|
1168
|
+
description: "Categorical chart series 5 of 20. Fill only; non-text 3:1 on chart surfaces (CP-055~CP-057). Series identity only; carries no magnitude."
|
|
1169
|
+
}),
|
|
1170
|
+
darkToken({
|
|
1171
|
+
key: "dataviz.series.6",
|
|
1172
|
+
usage: "nonText",
|
|
1173
|
+
value: "#54b21d",
|
|
1174
|
+
description: "Categorical chart series 6 of 20. Fill only; non-text 3:1 on chart surfaces (CP-058~CP-060). Series identity only; carries no magnitude."
|
|
1175
|
+
}),
|
|
1176
|
+
darkToken({
|
|
1177
|
+
key: "dataviz.series.7",
|
|
1178
|
+
usage: "nonText",
|
|
1179
|
+
value: "#ad8dec",
|
|
1180
|
+
description: "Categorical chart series 7 of 20. Fill only; non-text 3:1 on chart surfaces (CP-061~CP-063). Series identity only; carries no magnitude."
|
|
1181
|
+
}),
|
|
1182
|
+
darkToken({
|
|
1183
|
+
key: "dataviz.series.8",
|
|
1184
|
+
usage: "nonText",
|
|
1185
|
+
value: "#9fa41b",
|
|
1186
|
+
description: "Categorical chart series 8 of 20. Fill only; non-text 3:1 on chart surfaces (CP-064~CP-066). Series identity only; carries no magnitude."
|
|
1187
|
+
}),
|
|
1188
|
+
darkToken({
|
|
1189
|
+
key: "dataviz.series.9",
|
|
1190
|
+
usage: "nonText",
|
|
1191
|
+
value: "#7f9bea",
|
|
1192
|
+
description: "Categorical chart series 9 of 20. Fill only; non-text 3:1 on chart surfaces (CP-067~CP-069). Series identity only; carries no magnitude."
|
|
1193
|
+
}),
|
|
1194
|
+
darkToken({
|
|
1195
|
+
key: "dataviz.series.10",
|
|
1196
|
+
usage: "nonText",
|
|
1197
|
+
value: "#e18844",
|
|
1198
|
+
description: "Categorical chart series 10 of 20. Fill only; non-text 3:1 on chart surfaces (CP-070~CP-072). Series identity only; carries no magnitude."
|
|
1199
|
+
}),
|
|
1200
|
+
darkToken({
|
|
1201
|
+
key: "dataviz.series.11",
|
|
1202
|
+
usage: "nonText",
|
|
1203
|
+
value: "#20adc2",
|
|
1204
|
+
description: "Categorical chart series 11 of 20. Fill only; non-text 3:1 on chart surfaces (CP-073~CP-075). Series identity only; carries no magnitude."
|
|
1205
|
+
}),
|
|
1206
|
+
darkToken({
|
|
1207
|
+
key: "dataviz.series.12",
|
|
1208
|
+
usage: "nonText",
|
|
1209
|
+
value: "#ea7d8f",
|
|
1210
|
+
description: "Categorical chart series 12 of 20. Fill only; non-text 3:1 on chart surfaces (CP-076~CP-078). Series identity only; carries no magnitude."
|
|
1211
|
+
}),
|
|
1212
|
+
darkToken({
|
|
1213
|
+
key: "dataviz.series.13",
|
|
1214
|
+
usage: "nonText",
|
|
1215
|
+
value: "#1db46e",
|
|
1216
|
+
description: "Categorical chart series 13 of 20. Fill only; non-text 3:1 on chart surfaces (CP-079~CP-081). Series identity only; carries no magnitude."
|
|
1217
|
+
}),
|
|
1218
|
+
darkToken({
|
|
1219
|
+
key: "dataviz.series.14",
|
|
1220
|
+
usage: "nonText",
|
|
1221
|
+
value: "#e874cd",
|
|
1222
|
+
description: "Categorical chart series 14 of 20. Fill only; non-text 3:1 on chart surfaces (CP-082~CP-084). Series identity only; carries no magnitude."
|
|
1223
|
+
}),
|
|
1224
|
+
darkToken({
|
|
1225
|
+
key: "dataviz.series.15",
|
|
1226
|
+
usage: "nonText",
|
|
1227
|
+
value: "#28b61e",
|
|
1228
|
+
description: "Categorical chart series 15 of 20. Fill only; non-text 3:1 on chart surfaces (CP-085~CP-087). Series identity only; carries no magnitude."
|
|
1229
|
+
}),
|
|
1230
|
+
darkToken({
|
|
1231
|
+
key: "dataviz.series.16",
|
|
1232
|
+
usage: "nonText",
|
|
1233
|
+
value: "#c583eb",
|
|
1234
|
+
description: "Categorical chart series 16 of 20. Fill only; non-text 3:1 on chart surfaces (CP-088~CP-090). Series identity only; carries no magnitude."
|
|
1235
|
+
}),
|
|
1236
|
+
darkToken({
|
|
1237
|
+
key: "dataviz.series.17",
|
|
1238
|
+
usage: "nonText",
|
|
1239
|
+
value: "#7cac1c",
|
|
1240
|
+
description: "Categorical chart series 17 of 20. Fill only; non-text 3:1 on chart surfaces (CP-091~CP-093). Series identity only; carries no magnitude."
|
|
1241
|
+
}),
|
|
1242
|
+
darkToken({
|
|
1243
|
+
key: "dataviz.series.18",
|
|
1244
|
+
usage: "nonText",
|
|
1245
|
+
value: "#9794ee",
|
|
1246
|
+
description: "Categorical chart series 18 of 20. Fill only; non-text 3:1 on chart surfaces (CP-094~CP-096). Series identity only; carries no magnitude."
|
|
1247
|
+
}),
|
|
1248
|
+
darkToken({
|
|
1249
|
+
key: "dataviz.series.19",
|
|
1250
|
+
usage: "nonText",
|
|
1251
|
+
value: "#c39720",
|
|
1252
|
+
description: "Categorical chart series 19 of 20. Fill only; non-text 3:1 on chart surfaces (CP-097~CP-099). Series identity only; carries no magnitude."
|
|
1253
|
+
}),
|
|
1254
|
+
darkToken({
|
|
1255
|
+
key: "dataviz.series.20",
|
|
1256
|
+
usage: "nonText",
|
|
1257
|
+
value: "#52a4e3",
|
|
1258
|
+
description: "Categorical chart series 20 of 20. Fill only; non-text 3:1 on chart surfaces (CP-100~CP-102). Series identity only; carries no magnitude."
|
|
1259
|
+
}),
|
|
1260
|
+
darkToken({
|
|
1261
|
+
key: "dataviz.sequential.1",
|
|
1262
|
+
usage: "nonText",
|
|
1263
|
+
value: "#6960d1",
|
|
1264
|
+
description: "Sequential distribution step 1 of 5 (least prominent), single-hue luminance ramp. Fill only; non-text 3:1 on chart surfaces (CP-103~CP-105)."
|
|
1265
|
+
}),
|
|
1266
|
+
darkToken({
|
|
1267
|
+
key: "dataviz.sequential.2",
|
|
1268
|
+
usage: "nonText",
|
|
1269
|
+
value: "#847dd9",
|
|
1270
|
+
description: "Sequential distribution step 2 of 5 (step), single-hue luminance ramp. Fill only; non-text 3:1 on chart surfaces (CP-106~CP-108)."
|
|
1271
|
+
}),
|
|
1272
|
+
darkToken({
|
|
1273
|
+
key: "dataviz.sequential.3",
|
|
1274
|
+
usage: "nonText",
|
|
1275
|
+
value: "#9e98e1",
|
|
1276
|
+
description: "Sequential distribution step 3 of 5 (step), single-hue luminance ramp. Fill only; non-text 3:1 on chart surfaces (CP-109~CP-111)."
|
|
1277
|
+
}),
|
|
1278
|
+
darkToken({
|
|
1279
|
+
key: "dataviz.sequential.4",
|
|
1280
|
+
usage: "nonText",
|
|
1281
|
+
value: "#b7b3e9",
|
|
1282
|
+
description: "Sequential distribution step 4 of 5 (step), single-hue luminance ramp. Fill only; non-text 3:1 on chart surfaces (CP-112~CP-114)."
|
|
1283
|
+
}),
|
|
1284
|
+
darkToken({
|
|
1285
|
+
key: "dataviz.sequential.5",
|
|
1286
|
+
usage: "nonText",
|
|
1287
|
+
value: "#cecbf0",
|
|
1288
|
+
description: "Sequential distribution step 5 of 5 (most prominent), single-hue luminance ramp. Fill only; non-text 3:1 on chart surfaces (CP-115~CP-117)."
|
|
1289
|
+
})
|
|
1290
|
+
];
|
|
985
1291
|
var darkPalette = [
|
|
986
1292
|
...surface,
|
|
987
1293
|
...text,
|
|
@@ -992,7 +1298,8 @@ var darkPalette = [
|
|
|
992
1298
|
...severity,
|
|
993
1299
|
...fontFamily,
|
|
994
1300
|
...elevation,
|
|
995
|
-
...interaction
|
|
1301
|
+
...interaction,
|
|
1302
|
+
...dataviz
|
|
996
1303
|
];
|
|
997
1304
|
|
|
998
1305
|
// src/palette.light.ts
|
|
@@ -1006,6 +1313,8 @@ var values = {
|
|
|
1006
1313
|
"surface.glass": "rgba(251, 252, 253, 0.86)",
|
|
1007
1314
|
"surface.timeline": "#f1f4f8",
|
|
1008
1315
|
"surface.track": "rgba(12, 18, 28, 0.08)",
|
|
1316
|
+
"surface.tint.1": "rgba(79, 91, 213, 0.1)",
|
|
1317
|
+
"surface.tint.2": "rgba(4, 120, 87, 0.05)",
|
|
1009
1318
|
"text.primary": "#0c121c",
|
|
1010
1319
|
"text.secondary": "#33415a",
|
|
1011
1320
|
"text.muted": "#4d5a6e",
|
|
@@ -1036,12 +1345,58 @@ var values = {
|
|
|
1036
1345
|
"state.hover": "rgba(12, 18, 28, 0.05)",
|
|
1037
1346
|
"state.selected": "rgba(79, 91, 213, 0.12)",
|
|
1038
1347
|
"state.disabled": "#e2e8f0",
|
|
1039
|
-
"state.disabledPolicy": "#fef3c7"
|
|
1348
|
+
"state.disabledPolicy": "#fef3c7",
|
|
1349
|
+
// dataviz — chart series colours, darkened for light surfaces (CR-036).
|
|
1350
|
+
"dataviz.series.1": "#d45946",
|
|
1351
|
+
"dataviz.series.2": "#228f7d",
|
|
1352
|
+
"dataviz.series.3": "#d54e8d",
|
|
1353
|
+
"dataviz.series.4": "#22933d",
|
|
1354
|
+
"dataviz.series.5": "#ca45d3",
|
|
1355
|
+
"dataviz.series.6": "#4a9022",
|
|
1356
|
+
"dataviz.series.7": "#906adc",
|
|
1357
|
+
"dataviz.series.8": "#81851f",
|
|
1358
|
+
"dataviz.series.9": "#5a7cd8",
|
|
1359
|
+
"dataviz.series.10": "#bd6b2c",
|
|
1360
|
+
"dataviz.series.11": "#258c9c",
|
|
1361
|
+
"dataviz.series.12": "#d75369",
|
|
1362
|
+
"dataviz.series.13": "#22915d",
|
|
1363
|
+
"dataviz.series.14": "#d446b2",
|
|
1364
|
+
"dataviz.series.15": "#2a9322",
|
|
1365
|
+
"dataviz.series.16": "#ab5dd9",
|
|
1366
|
+
"dataviz.series.17": "#688b21",
|
|
1367
|
+
"dataviz.series.18": "#7773de",
|
|
1368
|
+
"dataviz.series.19": "#9b7c24",
|
|
1369
|
+
"dataviz.series.20": "#2f85c7",
|
|
1370
|
+
"dataviz.sequential.1": "#7d74dc",
|
|
1371
|
+
"dataviz.sequential.2": "#6e65d8",
|
|
1372
|
+
"dataviz.sequential.3": "#5c52d4",
|
|
1373
|
+
"dataviz.sequential.4": "#4539cd",
|
|
1374
|
+
"dataviz.sequential.5": "#3329a4"
|
|
1040
1375
|
};
|
|
1041
|
-
var
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1376
|
+
var lightAdditions = [];
|
|
1377
|
+
function derivePalette(base, overrides, additions = []) {
|
|
1378
|
+
const baseKeys = new Set(base.map((token) => token.key));
|
|
1379
|
+
const unmatched = Object.keys(overrides).filter((key) => !baseKeys.has(key));
|
|
1380
|
+
if (unmatched.length > 0) {
|
|
1381
|
+
throw new TokenBuildError("TOK-THEME-KEY", "theme override names a key the base palette does not declare", [
|
|
1382
|
+
...unmatched.map((key) => `override: ${key}`),
|
|
1383
|
+
"hint: the override would be dropped and the token would keep its dark value, which the key-set contract check cannot see. Fix the spelling, or declare the key in the base palette."
|
|
1384
|
+
]);
|
|
1385
|
+
}
|
|
1386
|
+
const notExempt = additions.filter((token) => token.themeSpecific !== true);
|
|
1387
|
+
if (notExempt.length > 0) {
|
|
1388
|
+
throw new TokenBuildError("TOK-THEME-KEY", "theme-only token is not marked `themeSpecific`", [
|
|
1389
|
+
...notExempt.map((token) => `addition: ${token.key}`),
|
|
1390
|
+
"hint: FR-QA-001 exempts a key from the cross-theme contract only when the token declares `themeSpecific: true`, so the exemption stays visible in the report."
|
|
1391
|
+
]);
|
|
1392
|
+
}
|
|
1393
|
+
const derived = base.map((token) => {
|
|
1394
|
+
const value2 = overrides[token.key];
|
|
1395
|
+
return value2 === void 0 ? token : { ...token, value: value2, alias: void 0 };
|
|
1396
|
+
});
|
|
1397
|
+
return [...derived, ...additions];
|
|
1398
|
+
}
|
|
1399
|
+
var lightPalette = derivePalette(darkPalette, values, lightAdditions);
|
|
1045
1400
|
|
|
1046
1401
|
// src/primitives.ts
|
|
1047
1402
|
function primitive(key, value2, description) {
|
|
@@ -1085,9 +1440,17 @@ var indigo = [
|
|
|
1085
1440
|
primitive("indigo.800", "#3f4ac0", "Light `accent.strong`.")
|
|
1086
1441
|
];
|
|
1087
1442
|
var slate = [
|
|
1088
|
-
primitive(
|
|
1443
|
+
primitive(
|
|
1444
|
+
"slate.400",
|
|
1445
|
+
"#94a3b8",
|
|
1446
|
+
"Base colour of all four dark border tokens and the scrollbar; dark `status.neutralEnd` (CR-035)."
|
|
1447
|
+
),
|
|
1089
1448
|
primitive("slate.500", "#64748b", "Dark `status.queued`; light `border.control`."),
|
|
1090
|
-
primitive(
|
|
1449
|
+
primitive(
|
|
1450
|
+
"slate.600",
|
|
1451
|
+
"#475569",
|
|
1452
|
+
"The source's `--status-neutral-end`. No consumer since CR-035 raised the dark end-state to `slate.400`; kept as the record of the source value that decision replaced."
|
|
1453
|
+
),
|
|
1091
1454
|
primitive("slate.700", "#3f4b5f", "Light `status.neutralEnd`."),
|
|
1092
1455
|
primitive("slate.750", "#52607a", "Light `status.queued`.")
|
|
1093
1456
|
];
|
|
@@ -1131,6 +1494,9 @@ var nonColour = [
|
|
|
1131
1494
|
primitive("scale.32", "32px", "Spacing step."),
|
|
1132
1495
|
primitive("scale.40", "40px", "Spacing step."),
|
|
1133
1496
|
primitive("scale.48", "48px", "Spacing step."),
|
|
1497
|
+
primitive("stroke.1", "1px", "Hairline width."),
|
|
1498
|
+
primitive("stroke.2", "2px", "Emphasis rule width."),
|
|
1499
|
+
primitive("stroke.3", "3px", "Status rail and active indicator width."),
|
|
1134
1500
|
primitive("curve.6", "6px", "Corner radius step."),
|
|
1135
1501
|
primitive("curve.9", "9px", "Corner radius step."),
|
|
1136
1502
|
primitive("curve.12", "12px", "Corner radius step."),
|
|
@@ -1391,22 +1757,71 @@ function measure(pair2, theme, index, values2) {
|
|
|
1391
1757
|
pass: ratio >= threshold
|
|
1392
1758
|
};
|
|
1393
1759
|
}
|
|
1760
|
+
function aliasTerminus(index, reference) {
|
|
1761
|
+
let key = resolveReferenceTarget(index, reference);
|
|
1762
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1763
|
+
while (key !== void 0 && !seen.has(key)) {
|
|
1764
|
+
seen.add(key);
|
|
1765
|
+
const alias = index.get(key)?.alias;
|
|
1766
|
+
if (alias === void 0) return key;
|
|
1767
|
+
key = resolveReferenceTarget(index, alias);
|
|
1768
|
+
}
|
|
1769
|
+
return key;
|
|
1770
|
+
}
|
|
1771
|
+
function assertNotForbidden(pair2, index, forbidden) {
|
|
1772
|
+
const resolvedForeground = aliasTerminus(index, pair2.foreground);
|
|
1773
|
+
const resolvedBackground = aliasTerminus(index, pair2.background);
|
|
1774
|
+
for (const banned of forbidden) {
|
|
1775
|
+
const bannedForeground = aliasTerminus(index, banned.foreground);
|
|
1776
|
+
const bannedBackground = aliasTerminus(index, banned.background);
|
|
1777
|
+
if (resolvedForeground !== bannedForeground || resolvedBackground !== bannedBackground) continue;
|
|
1778
|
+
if (banned.usages !== void 0 && !banned.usages.includes(pair2.usage)) continue;
|
|
1779
|
+
throw new TokenBuildError("TOK-CP-FORBIDDEN", "contrast pair declares a forbidden combination", [
|
|
1780
|
+
`pair: ${pair2.id} (${pair2.foreground} on ${pair2.background})`,
|
|
1781
|
+
`forbidden: ${banned.id} (${banned.foreground} on ${banned.background})`,
|
|
1782
|
+
`reason: ${banned.reason}`,
|
|
1783
|
+
"hint: the pair resolves to a combination that must not render. Lifting the ban needs a CR."
|
|
1784
|
+
]);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
function measureForbidden(forbidden, theme, index, values2) {
|
|
1788
|
+
return forbidden.map((banned) => {
|
|
1789
|
+
const asPair = { ...banned, usage: "nonText", themes: [theme] };
|
|
1790
|
+
const foreground = lookup(index, asPair, "foreground");
|
|
1791
|
+
const background = lookup(index, asPair, "background");
|
|
1792
|
+
const backgroundColor = colorOf(asPair, background, values2.get(background.key), "background");
|
|
1793
|
+
const foregroundColor = colorOf(asPair, foreground, values2.get(foreground.key), "foreground");
|
|
1794
|
+
const ratio = contrastRatio(compositeOver(foregroundColor, backgroundColor), backgroundColor);
|
|
1795
|
+
return {
|
|
1796
|
+
id: banned.id,
|
|
1797
|
+
theme,
|
|
1798
|
+
foreground: banned.foreground,
|
|
1799
|
+
background: banned.background,
|
|
1800
|
+
ratio: Number(ratio.toFixed(4)),
|
|
1801
|
+
reason: banned.reason
|
|
1802
|
+
};
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1394
1805
|
function exclusionsFor(tokens) {
|
|
1395
1806
|
return tokens.filter((token) => token.tier !== "primitive" && token.usage === "decorative").map((token) => ({ key: token.key, usage: "decorative", reason: token.description }));
|
|
1396
1807
|
}
|
|
1397
1808
|
function checkContrast(options = {}) {
|
|
1398
1809
|
const themes = options.themes ?? THEME_SOURCES;
|
|
1399
1810
|
const pairs = options.pairs ?? contrastPairs;
|
|
1811
|
+
const forbidden = options.forbidden ?? forbiddenPairs;
|
|
1400
1812
|
assertUniqueIds(pairs);
|
|
1401
1813
|
const results = [];
|
|
1402
1814
|
const exclusions = /* @__PURE__ */ new Map();
|
|
1815
|
+
const forbiddenResults = [];
|
|
1403
1816
|
for (const theme of themes) {
|
|
1404
1817
|
const tokens = tokensForTheme(theme);
|
|
1405
1818
|
const index = buildTokenIndex(tokens);
|
|
1406
1819
|
const { values: values2 } = resolveTokens(index);
|
|
1407
1820
|
for (const exclusion of exclusionsFor(tokens)) exclusions.set(exclusion.key, exclusion);
|
|
1821
|
+
forbiddenResults.push(...measureForbidden(forbidden, theme.theme, index, values2));
|
|
1408
1822
|
for (const pair2 of pairs) {
|
|
1409
1823
|
if (!pair2.themes.includes(theme.theme)) continue;
|
|
1824
|
+
assertNotForbidden(pair2, index, forbidden);
|
|
1410
1825
|
results.push(measure(pair2, theme.theme, index, values2));
|
|
1411
1826
|
}
|
|
1412
1827
|
}
|
|
@@ -1416,12 +1831,14 @@ function checkContrast(options = {}) {
|
|
|
1416
1831
|
thresholds: CONTRAST_THRESHOLDS,
|
|
1417
1832
|
results,
|
|
1418
1833
|
exclusions: [...exclusions.values()],
|
|
1834
|
+
forbidden: forbiddenResults,
|
|
1419
1835
|
summary: {
|
|
1420
1836
|
declaredPairs: pairs.length,
|
|
1421
1837
|
checks: results.length,
|
|
1422
1838
|
passed: results.length - failed,
|
|
1423
1839
|
failed,
|
|
1424
|
-
excludedTokens: exclusions.size
|
|
1840
|
+
excludedTokens: exclusions.size,
|
|
1841
|
+
forbiddenPairs: forbidden.length
|
|
1425
1842
|
}
|
|
1426
1843
|
};
|
|
1427
1844
|
}
|
|
@@ -1455,6 +1872,11 @@ function formatExclusions(report) {
|
|
|
1455
1872
|
lines.push(` ${exclusion.key}`);
|
|
1456
1873
|
lines.push(` reason: ${exclusion.reason}`);
|
|
1457
1874
|
}
|
|
1875
|
+
lines.push(`[contrast] ${report.summary.forbiddenPairs} combination(s) declared forbidden`);
|
|
1876
|
+
for (const banned of report.forbidden) {
|
|
1877
|
+
lines.push(` ${banned.id} ${banned.foreground} on ${banned.background} (theme=${banned.theme}, ${formatRatio(banned.ratio)}:1)`);
|
|
1878
|
+
lines.push(` reason: ${banned.reason}`);
|
|
1879
|
+
}
|
|
1458
1880
|
lines.push("[contrast] --report: no files written");
|
|
1459
1881
|
return lines;
|
|
1460
1882
|
}
|
|
@@ -1466,7 +1888,8 @@ function renderReportJson(report) {
|
|
|
1466
1888
|
thresholds: report.thresholds,
|
|
1467
1889
|
summary: report.summary,
|
|
1468
1890
|
results: report.results,
|
|
1469
|
-
exclusions: report.exclusions
|
|
1891
|
+
exclusions: report.exclusions,
|
|
1892
|
+
forbidden: report.forbidden
|
|
1470
1893
|
},
|
|
1471
1894
|
null,
|
|
1472
1895
|
2
|