@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 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
  };
@@ -73,7 +75,8 @@ function tierRank(tier) {
73
75
  var FIXED_GROUP_SIZES = {
74
76
  status: 7,
75
77
  severity: 4,
76
- meter: 3
78
+ meter: 3,
79
+ dataviz: 25
77
80
  };
78
81
  var ICON_REQUIRED_GROUPS = ["status", "severity"];
79
82
  function groupKeyOf(key) {
@@ -227,6 +230,11 @@ var radius = [
227
230
  aliased("radius.xl", "curve.24", "Largest radius."),
228
231
  semantic("radius.pill", "9999px", "Fully rounded badge, toggle, marker and progress geometry.")
229
232
  ];
233
+ var borderWidth = [
234
+ aliased("border.width.hairline", "stroke.1", "\uAE30\uBCF8 1px \uC5E3\uC9C0."),
235
+ aliased("border.width.emphasis", "stroke.2", "\uD45C \uD5E4\uB354 \uADDC\uCE59, \uB9C8\uCEE4 \uB9C1."),
236
+ aliased("border.width.rail", "stroke.3", "\uBC30\uB108 \uC0C1\uD0DC \uB808\uC77C, \uB0B4\uBE44 \uD65C\uC131 \uC778\uB514\uCF00\uC774\uD130.")
237
+ ];
230
238
  var Z_LAYERS = {
231
239
  base: 0,
232
240
  raised: 10,
@@ -269,6 +277,7 @@ var scaleTokens = [
269
277
  ...fontLineHeight,
270
278
  ...space,
271
279
  ...radius,
280
+ ...borderWidth,
272
281
  ...z,
273
282
  ...breakpoint,
274
283
  ...motion
@@ -352,14 +361,14 @@ var badge = [
352
361
  component("badge.marker.border", ref("border.strong"), "Marker-shape edge."),
353
362
  component("badge.marker.dotSize", value("9px"), "Status dot diameter."),
354
363
  component("badge.marker.dotRing", ref("surface.raised"), "Marker dot ring."),
355
- component("badge.marker.dotRingWidth", value("2px"), "Marker dot ring width."),
364
+ component("badge.marker.dotRingWidth", ref("border.width.emphasis"), "Marker dot ring width."),
356
365
  component("badge.severity.text", ref("text.primary"), "Label on a severity fill. 4.67:1 to 9.32:1.", "body")
357
366
  ];
358
367
  var table = [
359
368
  component("table.headerText", ref("text.muted"), "Column header text.", "body"),
360
369
  component("table.headerFontSize", ref("font.size.base"), "Column header size."),
361
370
  component("table.headerBorder", ref("border.default"), "Header rule."),
362
- component("table.headerBorderWidth", value("2px"), "Header rule width."),
371
+ component("table.headerBorderWidth", ref("border.width.emphasis"), "Header rule width."),
363
372
  component(
364
373
  "table.cellBorder",
365
374
  ref("border.default"),
@@ -471,6 +480,9 @@ var overlay = [
471
480
  ];
472
481
  var HEADING_MIN_PX = FONT_SIZE_PX.xl * 1.2;
473
482
  var HEADING_MAX_PX = FONT_SIZE_PX.xl * 1.6;
483
+ var H2_PX = Math.round(FONT_SIZE_PX.xl * 1.3);
484
+ var H3_PX = Math.round(FONT_SIZE_PX.xl * 1.1);
485
+ var HEADING_LINE_HEIGHT_RATIO = 1.3;
474
486
  var page = [
475
487
  component(
476
488
  "page.headingSize",
@@ -482,6 +494,26 @@ var page = [
482
494
  value("1.16"),
483
495
  "The only unitless line height: `clamp()` makes a px value impossible here."
484
496
  ),
497
+ component(
498
+ "page.sectionHeadingSize",
499
+ value(`${H2_PX}px`),
500
+ "`h2`. `font.size.xl` \xD7 1.3."
501
+ ),
502
+ component(
503
+ "page.sectionHeadingLineHeight",
504
+ value(`${roundHalfUp(H2_PX * HEADING_LINE_HEIGHT_RATIO)}px`),
505
+ "Line height paired with `page.sectionHeadingSize`, at the 1.30 heading ratio."
506
+ ),
507
+ component(
508
+ "page.subHeadingSize",
509
+ value(`${H3_PX}px`),
510
+ "`h3`. `font.size.xl` \xD7 1.1."
511
+ ),
512
+ component(
513
+ "page.subHeadingLineHeight",
514
+ value(`${roundHalfUp(H3_PX * HEADING_LINE_HEIGHT_RATIO)}px`),
515
+ "Line height paired with `page.subHeadingSize`, at the 1.30 heading ratio."
516
+ ),
485
517
  component("page.stackGap", ref("space.6"), "Gap between page sections."),
486
518
  component("page.stackGapCompact", ref("space.5"), "Section gap below `breakpoint.sm`."),
487
519
  component("page.contentStackGap", ref("space.5"), "Gap inside a content stack."),
@@ -494,12 +526,21 @@ var page = [
494
526
  component("page.skipLinkZ", ref("z.popover"), "Skip link stacking layer.")
495
527
  ];
496
528
  var shell = [
529
+ component(
530
+ "appShell.background",
531
+ 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}"),
532
+ "Ambient app-shell surface derived from the source application background."
533
+ ),
497
534
  component("appShell.navWidth", ref("page.shellNavWidth"), "AppShell desktop navigation width."),
498
535
  component("appShell.mainMaxWidth", value("1480px"), "AppShell main content maximum width."),
499
536
  component("appShell.overlayBackground", ref("surface.overlay"), "Mobile navigation scrim."),
500
537
  component("skipLink.background", ref("accent.DEFAULT"), "Skip-link fill."),
501
538
  component("skipLink.text", ref("text.inverse"), "Skip-link label."),
502
- component("navList.background", ref("surface.raised"), "Navigation surface."),
539
+ component(
540
+ "navList.background",
541
+ value("linear-gradient(180deg, {surface.glass}, {surface.canvas})"),
542
+ "Glass navigation surface over the app-shell ambient background."
543
+ ),
503
544
  component("navList.border", ref("border.subtle"), "Navigation surface edge."),
504
545
  component("navItem.text", ref("text.muted"), "Navigation item label."),
505
546
  component("navItem.textActive", ref("text.primary"), "Active navigation item label."),
@@ -597,6 +638,18 @@ var surface = [
597
638
  usage: "decorative",
598
639
  value: "rgba(255, 255, 255, 0.05)",
599
640
  description: "Progress and meter track, matching the source 1:1."
641
+ }),
642
+ darkToken({
643
+ key: "surface.tint.1",
644
+ usage: "decorative",
645
+ value: "rgba(109, 124, 255, 0.11)",
646
+ description: "Primary ambient glow from the source application background. Decorative only."
647
+ }),
648
+ darkToken({
649
+ key: "surface.tint.2",
650
+ usage: "decorative",
651
+ value: "rgba(20, 184, 166, 0.055)",
652
+ description: "Secondary ambient glow from the source application background. Decorative only."
600
653
  })
601
654
  ];
602
655
  var text = [
@@ -740,10 +793,10 @@ var status = [
740
793
  }),
741
794
  darkToken({
742
795
  key: "status.neutralEnd",
743
- usage: "decorative",
744
- value: "#475569",
796
+ usage: "nonText",
797
+ value: "#94a3b8",
745
798
  icon: "circle-slash",
746
- description: "Cancelled or superseded. Contrast-exempt per CR-006 (`srs_final.md` 12.1): 2.04:1 to 2.60:1 reaches non-text 3:1 on no surface. WCAG 1.4.11 exception \u2014 FR-THM-005 AC-7 forces an icon and a label alongside the colour, and the source's surface-coloured ring supplies the marker's shape boundary, so the dot's fill carries no identification on its own. Known cost: the dot reads faintly against a dark background."
799
+ 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."
747
800
  })
748
801
  ];
749
802
  var meter = [
@@ -862,6 +915,158 @@ var interaction = [
862
915
  description: "Policy-blocked fill. Contrast-exempt as a fill; checked beneath the label (5.27:1)."
863
916
  })
864
917
  ];
918
+ var dataviz = [
919
+ darkToken({
920
+ key: "dataviz.series.1",
921
+ usage: "nonText",
922
+ value: "#e88171",
923
+ 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."
924
+ }),
925
+ darkToken({
926
+ key: "dataviz.series.2",
927
+ usage: "nonText",
928
+ value: "#1db198",
929
+ 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."
930
+ }),
931
+ darkToken({
932
+ key: "dataviz.series.3",
933
+ usage: "nonText",
934
+ value: "#e979ad",
935
+ 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."
936
+ }),
937
+ darkToken({
938
+ key: "dataviz.series.4",
939
+ usage: "nonText",
940
+ value: "#1eb641",
941
+ 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."
942
+ }),
943
+ darkToken({
944
+ key: "dataviz.series.5",
945
+ usage: "nonText",
946
+ value: "#e073e8",
947
+ 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."
948
+ }),
949
+ darkToken({
950
+ key: "dataviz.series.6",
951
+ usage: "nonText",
952
+ value: "#54b21d",
953
+ 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."
954
+ }),
955
+ darkToken({
956
+ key: "dataviz.series.7",
957
+ usage: "nonText",
958
+ value: "#ad8dec",
959
+ 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."
960
+ }),
961
+ darkToken({
962
+ key: "dataviz.series.8",
963
+ usage: "nonText",
964
+ value: "#9fa41b",
965
+ 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."
966
+ }),
967
+ darkToken({
968
+ key: "dataviz.series.9",
969
+ usage: "nonText",
970
+ value: "#7f9bea",
971
+ 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."
972
+ }),
973
+ darkToken({
974
+ key: "dataviz.series.10",
975
+ usage: "nonText",
976
+ value: "#e18844",
977
+ 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."
978
+ }),
979
+ darkToken({
980
+ key: "dataviz.series.11",
981
+ usage: "nonText",
982
+ value: "#20adc2",
983
+ 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."
984
+ }),
985
+ darkToken({
986
+ key: "dataviz.series.12",
987
+ usage: "nonText",
988
+ value: "#ea7d8f",
989
+ 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."
990
+ }),
991
+ darkToken({
992
+ key: "dataviz.series.13",
993
+ usage: "nonText",
994
+ value: "#1db46e",
995
+ 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."
996
+ }),
997
+ darkToken({
998
+ key: "dataviz.series.14",
999
+ usage: "nonText",
1000
+ value: "#e874cd",
1001
+ 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."
1002
+ }),
1003
+ darkToken({
1004
+ key: "dataviz.series.15",
1005
+ usage: "nonText",
1006
+ value: "#28b61e",
1007
+ 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."
1008
+ }),
1009
+ darkToken({
1010
+ key: "dataviz.series.16",
1011
+ usage: "nonText",
1012
+ value: "#c583eb",
1013
+ 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."
1014
+ }),
1015
+ darkToken({
1016
+ key: "dataviz.series.17",
1017
+ usage: "nonText",
1018
+ value: "#7cac1c",
1019
+ 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."
1020
+ }),
1021
+ darkToken({
1022
+ key: "dataviz.series.18",
1023
+ usage: "nonText",
1024
+ value: "#9794ee",
1025
+ 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."
1026
+ }),
1027
+ darkToken({
1028
+ key: "dataviz.series.19",
1029
+ usage: "nonText",
1030
+ value: "#c39720",
1031
+ 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."
1032
+ }),
1033
+ darkToken({
1034
+ key: "dataviz.series.20",
1035
+ usage: "nonText",
1036
+ value: "#52a4e3",
1037
+ 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."
1038
+ }),
1039
+ darkToken({
1040
+ key: "dataviz.sequential.1",
1041
+ usage: "nonText",
1042
+ value: "#6960d1",
1043
+ 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)."
1044
+ }),
1045
+ darkToken({
1046
+ key: "dataviz.sequential.2",
1047
+ usage: "nonText",
1048
+ value: "#847dd9",
1049
+ 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)."
1050
+ }),
1051
+ darkToken({
1052
+ key: "dataviz.sequential.3",
1053
+ usage: "nonText",
1054
+ value: "#9e98e1",
1055
+ 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)."
1056
+ }),
1057
+ darkToken({
1058
+ key: "dataviz.sequential.4",
1059
+ usage: "nonText",
1060
+ value: "#b7b3e9",
1061
+ 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)."
1062
+ }),
1063
+ darkToken({
1064
+ key: "dataviz.sequential.5",
1065
+ usage: "nonText",
1066
+ value: "#cecbf0",
1067
+ 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)."
1068
+ })
1069
+ ];
865
1070
  var darkPalette = [
866
1071
  ...surface,
867
1072
  ...text,
@@ -872,7 +1077,8 @@ var darkPalette = [
872
1077
  ...severity,
873
1078
  ...fontFamily,
874
1079
  ...elevation,
875
- ...interaction
1080
+ ...interaction,
1081
+ ...dataviz
876
1082
  ];
877
1083
 
878
1084
  // src/palette.light.ts
@@ -886,6 +1092,8 @@ var values = {
886
1092
  "surface.glass": "rgba(251, 252, 253, 0.86)",
887
1093
  "surface.timeline": "#f1f4f8",
888
1094
  "surface.track": "rgba(12, 18, 28, 0.08)",
1095
+ "surface.tint.1": "rgba(79, 91, 213, 0.1)",
1096
+ "surface.tint.2": "rgba(4, 120, 87, 0.05)",
889
1097
  "text.primary": "#0c121c",
890
1098
  "text.secondary": "#33415a",
891
1099
  "text.muted": "#4d5a6e",
@@ -916,12 +1124,58 @@ var values = {
916
1124
  "state.hover": "rgba(12, 18, 28, 0.05)",
917
1125
  "state.selected": "rgba(79, 91, 213, 0.12)",
918
1126
  "state.disabled": "#e2e8f0",
919
- "state.disabledPolicy": "#fef3c7"
1127
+ "state.disabledPolicy": "#fef3c7",
1128
+ // dataviz — chart series colours, darkened for light surfaces (CR-036).
1129
+ "dataviz.series.1": "#d45946",
1130
+ "dataviz.series.2": "#228f7d",
1131
+ "dataviz.series.3": "#d54e8d",
1132
+ "dataviz.series.4": "#22933d",
1133
+ "dataviz.series.5": "#ca45d3",
1134
+ "dataviz.series.6": "#4a9022",
1135
+ "dataviz.series.7": "#906adc",
1136
+ "dataviz.series.8": "#81851f",
1137
+ "dataviz.series.9": "#5a7cd8",
1138
+ "dataviz.series.10": "#bd6b2c",
1139
+ "dataviz.series.11": "#258c9c",
1140
+ "dataviz.series.12": "#d75369",
1141
+ "dataviz.series.13": "#22915d",
1142
+ "dataviz.series.14": "#d446b2",
1143
+ "dataviz.series.15": "#2a9322",
1144
+ "dataviz.series.16": "#ab5dd9",
1145
+ "dataviz.series.17": "#688b21",
1146
+ "dataviz.series.18": "#7773de",
1147
+ "dataviz.series.19": "#9b7c24",
1148
+ "dataviz.series.20": "#2f85c7",
1149
+ "dataviz.sequential.1": "#7d74dc",
1150
+ "dataviz.sequential.2": "#6e65d8",
1151
+ "dataviz.sequential.3": "#5c52d4",
1152
+ "dataviz.sequential.4": "#4539cd",
1153
+ "dataviz.sequential.5": "#3329a4"
920
1154
  };
921
- var lightPalette = darkPalette.map((token) => {
922
- const value2 = values[token.key];
923
- return value2 === void 0 ? token : { ...token, value: value2, alias: void 0 };
924
- });
1155
+ var lightAdditions = [];
1156
+ function derivePalette(base, overrides, additions = []) {
1157
+ const baseKeys = new Set(base.map((token) => token.key));
1158
+ const unmatched = Object.keys(overrides).filter((key) => !baseKeys.has(key));
1159
+ if (unmatched.length > 0) {
1160
+ throw new TokenBuildError("TOK-THEME-KEY", "theme override names a key the base palette does not declare", [
1161
+ ...unmatched.map((key) => `override: ${key}`),
1162
+ "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."
1163
+ ]);
1164
+ }
1165
+ const notExempt = additions.filter((token) => token.themeSpecific !== true);
1166
+ if (notExempt.length > 0) {
1167
+ throw new TokenBuildError("TOK-THEME-KEY", "theme-only token is not marked `themeSpecific`", [
1168
+ ...notExempt.map((token) => `addition: ${token.key}`),
1169
+ "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."
1170
+ ]);
1171
+ }
1172
+ const derived = base.map((token) => {
1173
+ const value2 = overrides[token.key];
1174
+ return value2 === void 0 ? token : { ...token, value: value2, alias: void 0 };
1175
+ });
1176
+ return [...derived, ...additions];
1177
+ }
1178
+ var lightPalette = derivePalette(darkPalette, values, lightAdditions);
925
1179
 
926
1180
  // src/primitives.ts
927
1181
  function primitive(key, value2, description) {
@@ -965,9 +1219,17 @@ var indigo = [
965
1219
  primitive("indigo.800", "#3f4ac0", "Light `accent.strong`.")
966
1220
  ];
967
1221
  var slate = [
968
- primitive("slate.400", "#94a3b8", "Base colour of all four dark border tokens and the scrollbar."),
1222
+ primitive(
1223
+ "slate.400",
1224
+ "#94a3b8",
1225
+ "Base colour of all four dark border tokens and the scrollbar; dark `status.neutralEnd` (CR-035)."
1226
+ ),
969
1227
  primitive("slate.500", "#64748b", "Dark `status.queued`; light `border.control`."),
970
- primitive("slate.600", "#475569", "Dark `status.neutralEnd`."),
1228
+ primitive(
1229
+ "slate.600",
1230
+ "#475569",
1231
+ "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."
1232
+ ),
971
1233
  primitive("slate.700", "#3f4b5f", "Light `status.neutralEnd`."),
972
1234
  primitive("slate.750", "#52607a", "Light `status.queued`.")
973
1235
  ];
@@ -1011,6 +1273,9 @@ var nonColour = [
1011
1273
  primitive("scale.32", "32px", "Spacing step."),
1012
1274
  primitive("scale.40", "40px", "Spacing step."),
1013
1275
  primitive("scale.48", "48px", "Spacing step."),
1276
+ primitive("stroke.1", "1px", "Hairline width."),
1277
+ primitive("stroke.2", "2px", "Emphasis rule width."),
1278
+ primitive("stroke.3", "3px", "Status rail and active indicator width."),
1014
1279
  primitive("curve.6", "6px", "Corner radius step."),
1015
1280
  primitive("curve.9", "9px", "Corner radius step."),
1016
1281
  primitive("curve.12", "12px", "Corner radius step."),