@phcdevworks/spectre-tokens 2.7.0 → 2.9.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/README.md CHANGED
@@ -128,11 +128,12 @@ mode-aware styling.
128
128
 
129
129
  | Namespace | What it expresses |
130
130
  |---|---|
131
- | `surface` | Background roles: page, card, overlay, sidebar |
131
+ | `surface` | Background roles: page, card, overlay, sidebar, hover, selected, active, divider |
132
132
  | `text` | Foreground roles: default, muted, subtle, meta, on-surface, on-page |
133
- | `component` | Role-specific tokens for icon boxes, badges, ratings, testimonials, pricing cards |
133
+ | `component` | Role-specific tokens for icon boxes, badges, ratings, testimonials, pricing cards, nav, modal, toast, tooltip, dropdown |
134
134
  | `buttons` | Button state tokens: default, hover, active, disabled, CTA |
135
135
  | `forms` | Form state tokens: default, focused, error, disabled |
136
+ | `link` | Inline link color roles: default, hover, active, visited |
136
137
  | `modes` | Mode-aware overrides under `modes.default` and `modes.dark` |
137
138
 
138
139
  ```ts
@@ -252,6 +253,7 @@ The generated token object includes these namespaces:
252
253
  - `accessibility`
253
254
  - `buttons`
254
255
  - `forms`
256
+ - `link`
255
257
  - `surface`
256
258
  - `text`
257
259
  - `component`
@@ -427,14 +429,14 @@ npm install
427
429
  npm run check
428
430
  ```
429
431
 
430
- This project expects Node.js `^22.12.0 || >=24.0.0` and npm `11.14.1`.
432
+ This project expects Node.js `^22.12.0 || >=24.0.0` and npm `11.16.0`.
431
433
 
432
434
  ### Common commands
433
435
 
434
436
  | Command | What it does |
435
437
  |---|---|
436
438
  | `npm run build` | Regenerate all outputs — run after any token source change |
437
- | `npm run check` | Full validation gate — all 14 steps must pass before commit |
439
+ | `npm run check` | Full validation gate — all 15 steps must pass before commit |
438
440
  | `npm run lint` | Run ESLint against all source files |
439
441
  | `npm run format` | Apply Prettier formatting to all files |
440
442
  | `npm run generate` | Regenerate `src/generated/tokens.ts` from token sources only |
package/dist/index.cjs CHANGED
@@ -92,6 +92,61 @@ var coreTokens = {
92
92
  "starFilled": "{colors.warning.500}",
93
93
  "starEmpty": "{colors.neutral.200}",
94
94
  "text": "{colors.neutral.500}"
95
+ },
96
+ "nav": {
97
+ "bg": "{colors.white}",
98
+ "text": "{colors.neutral.900}",
99
+ "link": "{colors.neutral.700}",
100
+ "linkHover": "{colors.brand.600}",
101
+ "linkActive": "{colors.brand.700}",
102
+ "border": "{colors.neutral.200}"
103
+ },
104
+ "modal": {
105
+ "bg": "{colors.white}",
106
+ "shadow": "0 20px 48px -12px {colors.black} / 0.20",
107
+ "border": "{colors.neutral.200}",
108
+ "overlay": "{colors.black} / 0.6"
109
+ },
110
+ "toast": {
111
+ "success": {
112
+ "bg": "{colors.success.50}",
113
+ "text": "{colors.success.800}",
114
+ "border": "{colors.success.200}",
115
+ "icon": "{colors.success.600}"
116
+ },
117
+ "warning": {
118
+ "bg": "{colors.warning.50}",
119
+ "text": "{colors.warning.800}",
120
+ "border": "{colors.warning.200}",
121
+ "icon": "{colors.warning.600}"
122
+ },
123
+ "danger": {
124
+ "bg": "{colors.error.50}",
125
+ "text": "{colors.error.800}",
126
+ "border": "{colors.error.200}",
127
+ "icon": "{colors.error.600}"
128
+ },
129
+ "info": {
130
+ "bg": "{colors.info.50}",
131
+ "text": "{colors.info.800}",
132
+ "border": "{colors.info.200}",
133
+ "icon": "{colors.info.600}"
134
+ }
135
+ },
136
+ "tooltip": {
137
+ "bg": "{colors.neutral.900}",
138
+ "text": "{colors.white}",
139
+ "border": "{colors.neutral.700}"
140
+ },
141
+ "dropdown": {
142
+ "bg": "{colors.white}",
143
+ "border": "{colors.neutral.200}",
144
+ "item": {
145
+ "default": "transparent",
146
+ "hover": "{colors.neutral.100}",
147
+ "active": "{colors.info.50}",
148
+ "text": "{colors.neutral.900}"
149
+ }
95
150
  }
96
151
  },
97
152
  "buttons": {
@@ -134,7 +189,8 @@ var coreTokens = {
134
189
  "bgDisabled": "{colors.error.200}",
135
190
  "text": "{colors.white}",
136
191
  "textDisabled": "{colors.neutral.400}",
137
- "focusRing": "{colors.error.500} / 0.4"
192
+ "focusRing": "{colors.error.500} / 0.4",
193
+ "focusVisible": "{colors.error.500} / 0.4"
138
194
  },
139
195
  "success": {
140
196
  "bg": "{colors.success.700}",
@@ -143,7 +199,8 @@ var coreTokens = {
143
199
  "bgDisabled": "{colors.success.200}",
144
200
  "text": "{colors.white}",
145
201
  "textDisabled": "{colors.neutral.400}",
146
- "focusRing": "{colors.success.500} / 0.4"
202
+ "focusRing": "{colors.success.500} / 0.4",
203
+ "focusVisible": "{colors.success.500} / 0.4"
147
204
  },
148
205
  "cta": {
149
206
  "bg": "{colors.brand.600}",
@@ -208,7 +265,11 @@ var coreTokens = {
208
265
  "input": "{colors.white}",
209
266
  "overlay": "{colors.black} / 0.6",
210
267
  "alternate": "{colors.neutral.100}",
211
- "hero": "linear-gradient(135deg, {colors.indigo.500} 0%, {colors.violet.600} 100%)"
268
+ "hero": "linear-gradient(135deg, {colors.indigo.500} 0%, {colors.violet.600} 100%)",
269
+ "hover": "{colors.neutral.100}",
270
+ "selected": "{colors.info.50}",
271
+ "active": "{colors.neutral.200}",
272
+ "divider": "{colors.neutral.200}"
212
273
  },
213
274
  "text": {
214
275
  "onPage": {
@@ -285,6 +346,61 @@ var coreTokens = {
285
346
  "starFilled": "{colors.warning.500}",
286
347
  "starEmpty": "{colors.neutral.200}",
287
348
  "text": "{colors.neutral.500}"
349
+ },
350
+ "nav": {
351
+ "bg": "{colors.white}",
352
+ "text": "{colors.neutral.900}",
353
+ "link": "{colors.neutral.700}",
354
+ "linkHover": "{colors.brand.600}",
355
+ "linkActive": "{colors.brand.700}",
356
+ "border": "{colors.neutral.200}"
357
+ },
358
+ "modal": {
359
+ "bg": "{colors.white}",
360
+ "shadow": "0 20px 48px -12px {colors.black} / 0.20",
361
+ "border": "{colors.neutral.200}",
362
+ "overlay": "{colors.black} / 0.6"
363
+ },
364
+ "toast": {
365
+ "success": {
366
+ "bg": "{colors.success.50}",
367
+ "text": "{colors.success.800}",
368
+ "border": "{colors.success.200}",
369
+ "icon": "{colors.success.600}"
370
+ },
371
+ "warning": {
372
+ "bg": "{colors.warning.50}",
373
+ "text": "{colors.warning.800}",
374
+ "border": "{colors.warning.200}",
375
+ "icon": "{colors.warning.600}"
376
+ },
377
+ "danger": {
378
+ "bg": "{colors.error.50}",
379
+ "text": "{colors.error.800}",
380
+ "border": "{colors.error.200}",
381
+ "icon": "{colors.error.600}"
382
+ },
383
+ "info": {
384
+ "bg": "{colors.info.50}",
385
+ "text": "{colors.info.800}",
386
+ "border": "{colors.info.200}",
387
+ "icon": "{colors.info.600}"
388
+ }
389
+ },
390
+ "tooltip": {
391
+ "bg": "{colors.neutral.900}",
392
+ "text": "{colors.white}",
393
+ "border": "{colors.neutral.700}"
394
+ },
395
+ "dropdown": {
396
+ "bg": "{colors.white}",
397
+ "border": "{colors.neutral.200}",
398
+ "item": {
399
+ "default": "transparent",
400
+ "hover": "{colors.neutral.100}",
401
+ "active": "{colors.info.50}",
402
+ "text": "{colors.neutral.900}"
403
+ }
288
404
  }
289
405
  }
290
406
  },
@@ -295,7 +411,11 @@ var coreTokens = {
295
411
  "input": "{colors.neutral.700}",
296
412
  "overlay": "{colors.black} / 0.6",
297
413
  "alternate": "{colors.neutral.800}",
298
- "hero": "linear-gradient(135deg, {colors.accent.700} 0%, {colors.accent.900} 100%)"
414
+ "hero": "linear-gradient(135deg, {colors.accent.700} 0%, {colors.accent.900} 100%)",
415
+ "hover": "{colors.neutral.700}",
416
+ "selected": "{colors.info.900}",
417
+ "active": "{colors.neutral.600}",
418
+ "divider": "{colors.neutral.700}"
299
419
  },
300
420
  "text": {
301
421
  "onPage": {
@@ -375,6 +495,61 @@ var coreTokens = {
375
495
  "starFilled": "{colors.warning.400}",
376
496
  "starEmpty": "{colors.neutral.700}",
377
497
  "text": "{colors.neutral.400}"
498
+ },
499
+ "nav": {
500
+ "bg": "{colors.neutral.900}",
501
+ "text": "{colors.neutral.50}",
502
+ "link": "{colors.neutral.300}",
503
+ "linkHover": "{colors.brand.400}",
504
+ "linkActive": "{colors.brand.300}",
505
+ "border": "{colors.neutral.700}"
506
+ },
507
+ "modal": {
508
+ "bg": "{colors.neutral.800}",
509
+ "shadow": "0 20px 48px -12px {colors.black} / 0.20",
510
+ "border": "{colors.neutral.700}",
511
+ "overlay": "{colors.black} / 0.6"
512
+ },
513
+ "toast": {
514
+ "success": {
515
+ "bg": "{colors.success.900}",
516
+ "text": "{colors.success.100}",
517
+ "border": "{colors.success.700}",
518
+ "icon": "{colors.success.400}"
519
+ },
520
+ "warning": {
521
+ "bg": "{colors.warning.900}",
522
+ "text": "{colors.warning.100}",
523
+ "border": "{colors.warning.700}",
524
+ "icon": "{colors.warning.400}"
525
+ },
526
+ "danger": {
527
+ "bg": "{colors.error.900}",
528
+ "text": "{colors.error.100}",
529
+ "border": "{colors.error.700}",
530
+ "icon": "{colors.error.400}"
531
+ },
532
+ "info": {
533
+ "bg": "{colors.info.900}",
534
+ "text": "{colors.info.100}",
535
+ "border": "{colors.info.700}",
536
+ "icon": "{colors.info.400}"
537
+ }
538
+ },
539
+ "tooltip": {
540
+ "bg": "{colors.neutral.50}",
541
+ "text": "{colors.neutral.900}",
542
+ "border": "{colors.neutral.300}"
543
+ },
544
+ "dropdown": {
545
+ "bg": "{colors.neutral.800}",
546
+ "border": "{colors.neutral.700}",
547
+ "item": {
548
+ "default": "transparent",
549
+ "hover": "{colors.neutral.700}",
550
+ "active": "{colors.info.900}",
551
+ "text": "{colors.neutral.100}"
552
+ }
378
553
  }
379
554
  }
380
555
  }
@@ -472,26 +647,33 @@ var coreTokens = {
472
647
  "600": "#6f3fd7"
473
648
  },
474
649
  "focus": {
475
- "primary": "#336df4",
476
- "error": "#ef4444",
477
- "info": "#0369a1"
650
+ "primary": "{colors.brand.500}",
651
+ "error": "{colors.error.500}",
652
+ "info": "{colors.info.600}"
478
653
  },
479
654
  "white": "#ffffff",
480
655
  "black": "#000000"
481
656
  },
482
657
  "space": {
483
658
  "0": "0rem",
659
+ "1": "0.0625rem",
660
+ "2": "0.125rem",
484
661
  "4": "0.25rem",
662
+ "6": "0.375rem",
485
663
  "8": "0.5rem",
664
+ "10": "0.625rem",
486
665
  "12": "0.75rem",
666
+ "14": "0.875rem",
487
667
  "16": "1rem",
488
668
  "20": "1.25rem",
489
669
  "24": "1.5rem",
670
+ "28": "1.75rem",
490
671
  "32": "2rem",
491
672
  "40": "2.5rem",
492
673
  "48": "3rem",
493
674
  "56": "3.5rem",
494
675
  "64": "4rem",
676
+ "72": "4.5rem",
495
677
  "80": "5rem",
496
678
  "96": "6rem"
497
679
  },
@@ -502,6 +684,8 @@ var coreTokens = {
502
684
  "lg": "8px",
503
685
  "xl": "12px",
504
686
  "2xl": "16px",
687
+ "3xl": "24px",
688
+ "4xl": "32px",
505
689
  "pill": "999px"
506
690
  },
507
691
  "shadows": {
@@ -532,6 +716,7 @@ var coreTokens = {
532
716
  },
533
717
  "transitions": {
534
718
  "duration": {
719
+ "reduced": "0.01ms",
535
720
  "instant": "75ms",
536
721
  "fast": "150ms",
537
722
  "base": "200ms",
@@ -591,6 +776,48 @@ var coreTokens = {
591
776
  "duration": "{transitions.duration.slowest}",
592
777
  "easing": "{transitions.easing.spring}",
593
778
  "keyframes": "pulse"
779
+ },
780
+ "reducedMotion": {
781
+ "fadeIn": {
782
+ "duration": "{transitions.duration.reduced}",
783
+ "easing": "{transitions.easing.linear}",
784
+ "keyframes": "fade-in"
785
+ },
786
+ "fadeOut": {
787
+ "duration": "{transitions.duration.reduced}",
788
+ "easing": "{transitions.easing.linear}",
789
+ "keyframes": "fade-out"
790
+ },
791
+ "slideUp": {
792
+ "duration": "{transitions.duration.reduced}",
793
+ "easing": "{transitions.easing.linear}",
794
+ "keyframes": "slide-up"
795
+ },
796
+ "slideDown": {
797
+ "duration": "{transitions.duration.reduced}",
798
+ "easing": "{transitions.easing.linear}",
799
+ "keyframes": "slide-down"
800
+ },
801
+ "scaleIn": {
802
+ "duration": "{transitions.duration.reduced}",
803
+ "easing": "{transitions.easing.linear}",
804
+ "keyframes": "scale-in"
805
+ },
806
+ "bounce": {
807
+ "duration": "{transitions.duration.reduced}",
808
+ "easing": "{transitions.easing.linear}",
809
+ "keyframes": "bounce"
810
+ },
811
+ "shake": {
812
+ "duration": "{transitions.duration.reduced}",
813
+ "easing": "{transitions.easing.linear}",
814
+ "keyframes": "shake"
815
+ },
816
+ "pulse": {
817
+ "duration": "{transitions.duration.reduced}",
818
+ "easing": "{transitions.easing.linear}",
819
+ "keyframes": "pulse"
820
+ }
594
821
  }
595
822
  },
596
823
  "opacity": {
@@ -626,24 +853,39 @@ var coreTokens = {
626
853
  "offset": "2px",
627
854
  "style": "solid"
628
855
  },
856
+ "reducedMotion": "{transitions.duration.reduced}",
857
+ "forcedColors": "auto",
629
858
  "minTouchTarget": "44px",
630
859
  "minTextSize": "16px"
631
860
  },
632
861
  "border": {
633
862
  "width": {
863
+ "none": "0",
634
864
  "base": "1px",
635
865
  "thick": "2px"
636
866
  },
637
867
  "style": {
638
868
  "none": "none",
639
- "solid": "solid"
869
+ "solid": "solid",
870
+ "dashed": "dashed",
871
+ "dotted": "dotted"
640
872
  }
641
873
  },
642
874
  "surface": {
643
875
  "page": "{colors.neutral.50}",
644
876
  "card": "{colors.white}",
645
877
  "input": "{colors.white}",
646
- "overlay": "{colors.black} / 0.6"
878
+ "overlay": "{colors.black} / 0.6",
879
+ "hover": "{colors.neutral.100}",
880
+ "selected": "{colors.info.50}",
881
+ "active": "{colors.neutral.200}",
882
+ "divider": "{colors.neutral.200}"
883
+ },
884
+ "link": {
885
+ "default": "{colors.brand.600}",
886
+ "hover": "{colors.brand.700}",
887
+ "active": "{colors.brand.800}",
888
+ "visited": "{colors.accent.700}"
647
889
  },
648
890
  "text": {
649
891
  "onPage": {
@@ -846,6 +1088,42 @@ var ICON_BOX_FIELDS = [
846
1088
  { name: "icon-warning", tokenKey: "iconWarning" },
847
1089
  { name: "icon-danger", tokenKey: "iconDanger" }
848
1090
  ];
1091
+ var NAV_FIELDS = [
1092
+ { name: "bg", tokenKey: "bg" },
1093
+ { name: "text", tokenKey: "text" },
1094
+ { name: "link", tokenKey: "link" },
1095
+ { name: "link-hover", tokenKey: "linkHover" },
1096
+ { name: "link-active", tokenKey: "linkActive" },
1097
+ { name: "border", tokenKey: "border" }
1098
+ ];
1099
+ var MODAL_FIELDS = [
1100
+ { name: "bg", tokenKey: "bg" },
1101
+ { name: "shadow", tokenKey: "shadow" },
1102
+ { name: "border", tokenKey: "border" },
1103
+ { name: "overlay", tokenKey: "overlay" }
1104
+ ];
1105
+ var TOAST_VARIANTS = ["success", "warning", "danger", "info"].map((variant) => ({
1106
+ variant,
1107
+ fields: [
1108
+ { name: "bg", tokenKey: "bg" },
1109
+ { name: "text", tokenKey: "text" },
1110
+ { name: "border", tokenKey: "border" },
1111
+ { name: "icon", tokenKey: "icon" }
1112
+ ]
1113
+ }));
1114
+ var TOOLTIP_FIELDS = [
1115
+ { name: "bg", tokenKey: "bg" },
1116
+ { name: "text", tokenKey: "text" },
1117
+ { name: "border", tokenKey: "border" }
1118
+ ];
1119
+ var DROPDOWN_FIELDS = [
1120
+ { name: "bg", modePath: ["bg"], aliasPath: ["bg"] },
1121
+ { name: "border", modePath: ["border"], aliasPath: ["border"] },
1122
+ { name: "item-default", modePath: ["item", "default"], aliasPath: ["item", "default"] },
1123
+ { name: "item-hover", modePath: ["item", "hover"], aliasPath: ["item", "hover"] },
1124
+ { name: "item-active", modePath: ["item", "active"], aliasPath: ["item", "active"] },
1125
+ { name: "item-text", modePath: ["item", "text"], aliasPath: ["item", "text"] }
1126
+ ];
849
1127
  var resolveTokenReference = (tokens2, reference) => {
850
1128
  const path = reference.slice(1, -1).split(".");
851
1129
  let current = tokens2;
@@ -1013,6 +1291,7 @@ var createCssVariableMap = (tokens2, options = {}) => {
1013
1291
  assign(toVariableName(prefix, "focus-ring-style"), baseTokens.accessibility.focusRing.style);
1014
1292
  assign(toVariableName(prefix, "min-touch-target"), baseTokens.accessibility.minTouchTarget);
1015
1293
  assign(toVariableName(prefix, "min-text-size"), baseTokens.accessibility.minTextSize);
1294
+ assign(toVariableName(prefix, "reduced-motion"), baseTokens.accessibility.reducedMotion);
1016
1295
  Object.entries(baseTokens.buttons).forEach(([variant, states]) => {
1017
1296
  Object.entries(states).forEach(([state, value]) => {
1018
1297
  assign(toVariableName(prefix, "button", variant, state), value);
@@ -1024,11 +1303,22 @@ var createCssVariableMap = (tokens2, options = {}) => {
1024
1303
  });
1025
1304
  });
1026
1305
  if (baseTokens.animations) {
1027
- Object.entries(baseTokens.animations).forEach(([name, animation]) => {
1028
- assign(toVariableName(prefix, "animation", name, "duration"), animation.duration);
1029
- assign(toVariableName(prefix, "animation", name, "easing"), animation.easing);
1030
- assign(toVariableName(prefix, "animation", name, "keyframes"), animation.keyframes);
1031
- });
1306
+ Object.entries(baseTokens.animations).forEach(
1307
+ ([name, animation]) => {
1308
+ if (name === "reducedMotion") {
1309
+ Object.entries(animation).forEach(([subName, subAnimation]) => {
1310
+ assign(toVariableName(prefix, "animation", "reduced-motion", subName, "duration"), subAnimation.duration);
1311
+ assign(toVariableName(prefix, "animation", "reduced-motion", subName, "easing"), subAnimation.easing);
1312
+ assign(toVariableName(prefix, "animation", "reduced-motion", subName, "keyframes"), subAnimation.keyframes);
1313
+ });
1314
+ } else {
1315
+ const entry = animation;
1316
+ assign(toVariableName(prefix, "animation", name, "duration"), entry.duration);
1317
+ assign(toVariableName(prefix, "animation", name, "easing"), entry.easing);
1318
+ assign(toVariableName(prefix, "animation", name, "keyframes"), entry.keyframes);
1319
+ }
1320
+ }
1321
+ );
1032
1322
  }
1033
1323
  return map;
1034
1324
  };
@@ -1074,6 +1364,36 @@ var generateCssVariables = (tokens2, options = {}) => {
1074
1364
  modePath: ["component", "iconBox", tokenKey],
1075
1365
  aliasSrc: componentAliases,
1076
1366
  aliasPath: ["iconBox", tokenKey]
1367
+ })),
1368
+ ...NAV_FIELDS.map(({ name, tokenKey }) => ({
1369
+ varParts: ["nav", name],
1370
+ modePath: ["component", "nav", tokenKey],
1371
+ aliasSrc: componentAliases,
1372
+ aliasPath: ["nav", tokenKey]
1373
+ })),
1374
+ ...MODAL_FIELDS.map(({ name, tokenKey }) => ({
1375
+ varParts: ["modal", name],
1376
+ modePath: ["component", "modal", tokenKey],
1377
+ aliasSrc: componentAliases,
1378
+ aliasPath: ["modal", tokenKey]
1379
+ })),
1380
+ ...TOAST_VARIANTS.flatMap(({ variant, fields }) => fields.map(({ name, tokenKey }) => ({
1381
+ varParts: ["toast", variant, name],
1382
+ modePath: ["component", "toast", variant, tokenKey],
1383
+ aliasSrc: componentAliases,
1384
+ aliasPath: ["toast", variant, tokenKey]
1385
+ }))),
1386
+ ...TOOLTIP_FIELDS.map(({ name, tokenKey }) => ({
1387
+ varParts: ["tooltip", name],
1388
+ modePath: ["component", "tooltip", tokenKey],
1389
+ aliasSrc: componentAliases,
1390
+ aliasPath: ["tooltip", tokenKey]
1391
+ })),
1392
+ ...DROPDOWN_FIELDS.map(({ name, modePath, aliasPath }) => ({
1393
+ varParts: ["dropdown", name],
1394
+ modePath: ["component", "dropdown", ...modePath],
1395
+ aliasSrc: componentAliases,
1396
+ aliasPath: ["dropdown", ...aliasPath]
1077
1397
  }))
1078
1398
  ];
1079
1399
  const baseLines = [];