@verdify/tokens 0.6.0 → 0.8.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.
@@ -10,8 +10,56 @@
10
10
  [data-adaptive="dusk"] {
11
11
  --color-surface-canvas: #1a1a26;
12
12
  --color-text-primary: #c8d0de;
13
+ --color-surface-raised: #1f2638;
14
+ --color-surface-input: #1f2638;
15
+ --color-surface-border: #4a5567;
16
+ --color-surface-border-muted: #2a3142;
17
+ --color-text-secondary: #8a95a8;
18
+ --color-text-muted: #4a5567;
19
+ --color-text-disabled: #2a3142;
20
+ --color-text-inverse: #0b0f19;
21
+ --color-action-secondary-bg: #1f2638;
22
+ --color-action-secondary-fg: #c8d0de;
23
+ --color-action-secondary-border: #4a5567;
24
+ --color-action-secondary-bg-hover: #1f2638;
25
+ --color-action-ghost-fg: #c8d0de;
26
+ --color-action-ghost-bg-hover: #1f2638;
27
+ --color-border-default: #4a5567;
28
+ --color-border-strong: #2a3142;
29
+ --color-control-bg: #1f2638;
30
+ --color-control-border: #4a5567;
31
+ --color-control-fg: #c8d0de;
32
+ --color-control-placeholder: #4a5567;
33
+ --color-status-verified-on-surface: #00d17a;
34
+ --color-status-signal-on-surface: #4d9dff;
35
+ --color-status-caution-on-surface: #f5a623;
36
+ --color-status-critical-on-surface: #ff4d4d;
13
37
  }
14
38
  [data-adaptive="night"] {
15
39
  --color-surface-canvas: #060912;
16
40
  --color-text-primary: #c8d0de;
41
+ --color-surface-raised: #0f1320;
42
+ --color-surface-input: #161b2a;
43
+ --color-surface-border: #1f2638;
44
+ --color-surface-border-muted: #2a3142;
45
+ --color-text-secondary: #8a95a8;
46
+ --color-text-muted: #4a5567;
47
+ --color-text-disabled: #2a3142;
48
+ --color-text-inverse: #0b0f19;
49
+ --color-action-secondary-bg: #0f1320;
50
+ --color-action-secondary-fg: #c8d0de;
51
+ --color-action-secondary-border: #1f2638;
52
+ --color-action-secondary-bg-hover: #161b2a;
53
+ --color-action-ghost-fg: #c8d0de;
54
+ --color-action-ghost-bg-hover: #0f1320;
55
+ --color-border-default: #1f2638;
56
+ --color-border-strong: #2a3142;
57
+ --color-control-bg: #161b2a;
58
+ --color-control-border: #1f2638;
59
+ --color-control-fg: #c8d0de;
60
+ --color-control-placeholder: #4a5567;
61
+ --color-status-verified-on-surface: #00d17a;
62
+ --color-status-signal-on-surface: #4d9dff;
63
+ --color-status-caution-on-surface: #f5a623;
64
+ --color-status-critical-on-surface: #ff4d4d;
17
65
  }
package/dist/preset.css CHANGED
@@ -10,6 +10,7 @@
10
10
  --breakpoint-xl: 80rem;
11
11
  --breakpoint-2xl: 96rem;
12
12
  --color-brand-brand: #7c5cff;
13
+ --color-brand-brand-strong: #7053e5;
13
14
  --color-brand-brand-deep: #5b3ee8;
14
15
  --color-neutral-obsidian-300: #c8d0de;
15
16
  --color-neutral-obsidian-400: #8a95a8;
@@ -50,9 +51,9 @@
50
51
  --color-text-on-brand: #fbfcfe;
51
52
  --color-scrim-light: rgba(11, 15, 25, 0.5);
52
53
  --color-scrim-dark: rgba(6, 9, 18, 0.7);
53
- --color-action-primary-bg: #7c5cff;
54
+ --color-action-primary-bg: #7053e5;
54
55
  --color-action-primary-fg: #fbfcfe;
55
- --color-action-primary-border: #7c5cff;
56
+ --color-action-primary-border: #7053e5;
56
57
  --color-action-primary-bg-hover: #5b3ee8;
57
58
  --color-action-primary-bg-active: #5b3ee8;
58
59
  --color-action-secondary-bg: #e8ecf4;
@@ -61,22 +62,26 @@
61
62
  --color-action-secondary-bg-hover: #d6dce8;
62
63
  --color-action-ghost-fg: #0b0f19;
63
64
  --color-action-ghost-bg-hover: #e8ecf4;
64
- --color-action-destructive-bg: #ff4d4d;
65
+ --color-action-destructive-bg: #be3939;
65
66
  --color-action-destructive-fg: #fbfcfe;
66
- --color-action-destructive-border: #ff4d4d;
67
+ --color-action-destructive-border: #be3939;
67
68
  --color-status-verified-fg: #007947;
69
+ --color-status-verified-on-surface: #007947;
68
70
  --color-status-verified-bg: #e8ecf4;
69
71
  --color-status-verified-border: #007947;
70
72
  --color-status-verified-accent: #00d17a;
71
73
  --color-status-signal-fg: #346bad;
74
+ --color-status-signal-on-surface: #346bad;
72
75
  --color-status-signal-bg: #e8ecf4;
73
76
  --color-status-signal-border: #346bad;
74
77
  --color-status-signal-accent: #4d9dff;
75
78
  --color-status-caution-fg: #8e6014;
79
+ --color-status-caution-on-surface: #8e6014;
76
80
  --color-status-caution-bg: #e8ecf4;
77
81
  --color-status-caution-border: #8e6014;
78
82
  --color-status-caution-accent: #f5a623;
79
83
  --color-status-critical-fg: #be3939;
84
+ --color-status-critical-on-surface: #be3939;
80
85
  --color-status-critical-bg: #e8ecf4;
81
86
  --color-status-critical-border: #be3939;
82
87
  --color-status-critical-accent: #ff4d4d;
package/dist/tokens.css CHANGED
@@ -13,6 +13,7 @@
13
13
  --breakpoint-xl: 80rem; /** Extra large breakpoint (1280px) — desktops */
14
14
  --breakpoint-2xl: 96rem; /** 2X large breakpoint (1536px) — wide desktops */
15
15
  --color-brand-brand: #7c5cff; /** Sovereign Violet — the single brand anchor. Identity color; the logo seam and primary brand moments. Sits outside the traffic-light status register. */
16
+ --color-brand-brand-strong: #7053e5; /** AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only. */
16
17
  --color-brand-brand-deep: #5b3ee8; /** Companion to brand.brand — used on light surfaces where #7C5CFF fails WCAG 2.2 non-text contrast (>=3:1). Luminance shift only. */
17
18
  --color-neutral-obsidian-300: #c8d0de; /** Primary text on dark */
18
19
  --color-neutral-obsidian-400: #8a95a8; /** Secondary text */
@@ -59,11 +60,23 @@
59
60
  --color-text-disabled: #b0baca; /** Disabled text — low-contrast, deliberate. Aliases mist.400; downstream consumers may alternatively compose text.primary with state.opacity.disabled (0.38) for a different visual register. */
60
61
  --color-text-inverse: #fbfcfe; /** Text on dark surfaces (e.g. obsidian backdrop, dark scrim). Aliases mist.50 — the lightest neutral. Distinct from on-brand: inverse is for neutral-dark contexts; on-brand is reserved for brand backgrounds. */
61
62
  --color-text-on-brand: #fbfcfe; /** Text on brand backgrounds (e.g. CTA buttons). Constant per brand discipline. */
63
+ --color-dark-surface-raised: #0f1320; /** Raised surface · cards — dark family (dusk/night). Mirrors surface.raised in light. */
64
+ --color-dark-surface-input: #161b2a; /** Input / well — dark family (dusk/night). */
65
+ --color-dark-surface-border: #1f2638; /** Border / divider — dark family (dusk/night). */
66
+ --color-dark-surface-border-muted: #2a3142; /** Muted border — dark family (dusk/night). */
67
+ --color-dark-text-secondary: #8a95a8; /** Secondary text — dark family (dusk/night); 6.6:1 on night canvas. */
68
+ --color-dark-text-muted: #4a5567; /** Muted text — dark family; de-emphasized, same sub-UI register as light muted (~2.3-2.6:1). */
69
+ --color-dark-text-disabled: #2a3142; /** Disabled text — dark family; low-contrast, deliberate (contrast-exempt). */
70
+ --color-dark-text-inverse: #0b0f19; /** Text on light surfaces within a dark context — dark family. (0 current component uses.) */
71
+ --color-dusk-surface-raised: #1f2638; /** Raised surface · cards — DUSK band only. The dusk canvas (#1a1a26, L≈0.011) is lighter than the shared dark family's raised (obsidian.850, L≈0.0067), which inverted elevation. Obsidian.700 (L≈0.0196) sits ABOVE the dusk canvas so cards read raised, while secondary text still clears AA (≈5.0:1). */
72
+ --color-dusk-surface-input: #1f2638; /** Input / well — DUSK band only. Same tone as dusk raised (lifted above the dusk canvas); distinguished from cards by its border. Obsidian.700 keeps muted text at the ≈2.0:1 perceptible floor (obsidian.600 would drop it to ~1.7:1 and fail). */
73
+ --color-dusk-surface-border: #4a5567; /** Border / divider — DUSK band only. Obsidian.500 (L≈0.089) gives inputs/cards a visible boundary on the dusk canvas (≈2.3:1) where the shared dark border (obsidian.700) would be ~invisible. */
74
+ --color-dusk-surface-border-muted: #2a3142; /** Muted border — DUSK band only; the softer divider above the dusk canvas. */
62
75
  --color-scrim-light: rgba(11, 15, 25, 0.5); /** Modal/sheet backdrop on light surfaces — obsidian-900 at 50% opacity (per BR-2 spec §4). */
63
76
  --color-scrim-dark: rgba(6, 9, 18, 0.7); /** Modal/sheet backdrop on dark surfaces — obsidian-950 at 70% opacity for stronger isolation. */
64
- --color-action-primary-bg: #7c5cff; /** Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. */
77
+ --color-action-primary-bg: #7053e5; /** Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. — AA-darkened (brand-strong, 5.04:1 with white). */
65
78
  --color-action-primary-fg: #fbfcfe; /** Text/icon on a primary action. */
66
- --color-action-primary-border: #7c5cff; /** Primary action border — matches bg. */
79
+ --color-action-primary-border: #7053e5; /** Primary action border — matches bg. — AA-darkened (brand-strong, 5.04:1 with white). */
67
80
  --color-action-primary-bg-hover: #5b3ee8; /** Primary action hover — deep companion. */
68
81
  --color-action-primary-bg-active: #5b3ee8; /** Primary action pressed/active. */
69
82
  --color-action-secondary-bg: #e8ecf4; /** Secondary action background — neutral raised surface. */
@@ -72,22 +85,26 @@
72
85
  --color-action-secondary-bg-hover: #d6dce8; /** Secondary action hover. */
73
86
  --color-action-ghost-fg: #0b0f19; /** Ghost action text/icon — no fill until hover. */
74
87
  --color-action-ghost-bg-hover: #e8ecf4; /** Ghost action hover fill. */
75
- --color-action-destructive-bg: #ff4d4d; /** Destructive action background — Critical. A status color used for a destructive control; never the brand. */
88
+ --color-action-destructive-bg: #be3939; /** Destructive action background — Critical. A status color used for a destructive control; never the brand. — AA-darkened (critical-strong, 5.34:1 with white). */
76
89
  --color-action-destructive-fg: #fbfcfe; /** Text/icon on a destructive action. */
77
- --color-action-destructive-border: #ff4d4d; /** Destructive action border. */
90
+ --color-action-destructive-border: #be3939; /** Destructive action border. — AA-darkened (critical-strong, 5.34:1 with white). */
78
91
  --color-status-verified-fg: #007947; /** Verified status foreground — Verified Green darkened to WCAG AA (#007947, ≥4.5:1 on the chip bg). The in-product success state; never the brand. */
92
+ --color-status-verified-on-surface: #007947; /** Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip. */
79
93
  --color-status-verified-bg: #e8ecf4; /** Verified status chip background — neutral; color carried by fg/border (restraint over volume). */
80
94
  --color-status-verified-border: #007947; /** Verified status border — AA-dark shade (≥3:1 non-text). */
81
95
  --color-status-verified-accent: #00d17a; /** Verified bright decorative accent (#00D17A) — for icons/fills where contrast is not a text/border requirement. */
82
96
  --color-status-signal-fg: #346bad; /** Informational status foreground — Signal darkened to WCAG AA (#346BAD, ≥4.5:1 on the chip bg). */
97
+ --color-status-signal-on-surface: #346bad; /** Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip. */
83
98
  --color-status-signal-bg: #e8ecf4; /** Informational status chip background — neutral. */
84
99
  --color-status-signal-border: #346bad; /** Informational status border — AA-dark shade (≥3:1 non-text). */
85
100
  --color-status-signal-accent: #4d9dff; /** Signal bright decorative accent (#4D9DFF) — for icons/fills. */
86
101
  --color-status-caution-fg: #8e6014; /** Caution status foreground — Caution darkened to WCAG AA (#8E6014, ≥4.5:1 on the chip bg); pending / in-progress. */
102
+ --color-status-caution-on-surface: #8e6014; /** Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip. */
87
103
  --color-status-caution-bg: #e8ecf4; /** Caution status chip background — neutral. */
88
104
  --color-status-caution-border: #8e6014; /** Caution status border — AA-dark shade (≥3:1 non-text). */
89
105
  --color-status-caution-accent: #f5a623; /** Caution bright decorative accent (#F5A623) — for icons/fills. */
90
106
  --color-status-critical-fg: #be3939; /** Critical status foreground — Critical darkened to WCAG AA (#BE3939, ≥4.5:1 on the chip bg); error / failure. */
107
+ --color-status-critical-on-surface: #be3939; /** Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip. */
91
108
  --color-status-critical-bg: #e8ecf4; /** Critical status chip background — neutral. */
92
109
  --color-status-critical-border: #be3939; /** Critical status border — AA-dark shade (≥3:1 non-text). */
93
110
  --color-status-critical-accent: #ff4d4d; /** Critical bright decorative accent (#FF4D4D) — for icons/fills. */
package/dist/tokens.d.ts CHANGED
@@ -31,6 +31,7 @@ declare const tokens: {
31
31
  color: {
32
32
  brand: {
33
33
  brand: DesignToken;
34
+ "brand-strong": DesignToken;
34
35
  "brand-deep": DesignToken;
35
36
  };
36
37
  neutral: {
@@ -100,6 +101,28 @@ declare const tokens: {
100
101
  inverse: DesignToken;
101
102
  "on-brand": DesignToken;
102
103
  };
104
+ dark: {
105
+ surface: {
106
+ raised: DesignToken;
107
+ input: DesignToken;
108
+ border: DesignToken;
109
+ "border-muted": DesignToken;
110
+ };
111
+ text: {
112
+ secondary: DesignToken;
113
+ muted: DesignToken;
114
+ disabled: DesignToken;
115
+ inverse: DesignToken;
116
+ };
117
+ };
118
+ dusk: {
119
+ surface: {
120
+ raised: DesignToken;
121
+ input: DesignToken;
122
+ border: DesignToken;
123
+ "border-muted": DesignToken;
124
+ };
125
+ };
103
126
  scrim: {
104
127
  light: DesignToken;
105
128
  dark: DesignToken;
@@ -131,24 +154,28 @@ declare const tokens: {
131
154
  status: {
132
155
  verified: {
133
156
  fg: DesignToken;
157
+ "on-surface": DesignToken;
134
158
  bg: DesignToken;
135
159
  border: DesignToken;
136
160
  accent: DesignToken;
137
161
  };
138
162
  signal: {
139
163
  fg: DesignToken;
164
+ "on-surface": DesignToken;
140
165
  bg: DesignToken;
141
166
  border: DesignToken;
142
167
  accent: DesignToken;
143
168
  };
144
169
  caution: {
145
170
  fg: DesignToken;
171
+ "on-surface": DesignToken;
146
172
  bg: DesignToken;
147
173
  border: DesignToken;
148
174
  accent: DesignToken;
149
175
  };
150
176
  critical: {
151
177
  fg: DesignToken;
178
+ "on-surface": DesignToken;
152
179
  bg: DesignToken;
153
180
  border: DesignToken;
154
181
  accent: DesignToken;
package/dist/tokens.js CHANGED
@@ -196,6 +196,27 @@ module.exports = {
196
196
  },
197
197
  path: ["color", "brand", "brand"],
198
198
  },
199
+ "brand-strong": {
200
+ $value: "#7053e5",
201
+ $type: "color",
202
+ $description:
203
+ "AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only.",
204
+ filePath: "src/tokens/color.tokens.json",
205
+ isSource: true,
206
+ original: {
207
+ $value: "#7053E5",
208
+ $type: "color",
209
+ $description:
210
+ "AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only.",
211
+ },
212
+ name: "ColorBrandBrandStrong",
213
+ attributes: {
214
+ category: "color",
215
+ type: "brand",
216
+ item: "brand-strong",
217
+ },
218
+ path: ["color", "brand", "brand-strong"],
219
+ },
199
220
  "brand-deep": {
200
221
  $value: "#5b3ee8",
201
222
  $type: "color",
@@ -1155,6 +1176,274 @@ module.exports = {
1155
1176
  path: ["color", "text", "on-brand"],
1156
1177
  },
1157
1178
  },
1179
+ dark: {
1180
+ surface: {
1181
+ raised: {
1182
+ $value: "#0f1320",
1183
+ $type: "color",
1184
+ $description:
1185
+ "Raised surface · cards — dark family (dusk/night). Mirrors surface.raised in light.",
1186
+ filePath: "src/tokens/color.tokens.json",
1187
+ isSource: true,
1188
+ original: {
1189
+ $value: "{color.neutral.obsidian.850}",
1190
+ $type: "color",
1191
+ $description:
1192
+ "Raised surface · cards — dark family (dusk/night). Mirrors surface.raised in light.",
1193
+ },
1194
+ name: "ColorDarkSurfaceRaised",
1195
+ attributes: {
1196
+ category: "color",
1197
+ type: "dark",
1198
+ item: "surface",
1199
+ subitem: "raised",
1200
+ },
1201
+ path: ["color", "dark", "surface", "raised"],
1202
+ },
1203
+ input: {
1204
+ $value: "#161b2a",
1205
+ $type: "color",
1206
+ $description: "Input / well — dark family (dusk/night).",
1207
+ filePath: "src/tokens/color.tokens.json",
1208
+ isSource: true,
1209
+ original: {
1210
+ $value: "{color.neutral.obsidian.800}",
1211
+ $type: "color",
1212
+ $description: "Input / well — dark family (dusk/night).",
1213
+ },
1214
+ name: "ColorDarkSurfaceInput",
1215
+ attributes: {
1216
+ category: "color",
1217
+ type: "dark",
1218
+ item: "surface",
1219
+ subitem: "input",
1220
+ },
1221
+ path: ["color", "dark", "surface", "input"],
1222
+ },
1223
+ border: {
1224
+ $value: "#1f2638",
1225
+ $type: "color",
1226
+ $description: "Border / divider — dark family (dusk/night).",
1227
+ filePath: "src/tokens/color.tokens.json",
1228
+ isSource: true,
1229
+ original: {
1230
+ $value: "{color.neutral.obsidian.700}",
1231
+ $type: "color",
1232
+ $description: "Border / divider — dark family (dusk/night).",
1233
+ },
1234
+ name: "ColorDarkSurfaceBorder",
1235
+ attributes: {
1236
+ category: "color",
1237
+ type: "dark",
1238
+ item: "surface",
1239
+ subitem: "border",
1240
+ },
1241
+ path: ["color", "dark", "surface", "border"],
1242
+ },
1243
+ "border-muted": {
1244
+ $value: "#2a3142",
1245
+ $type: "color",
1246
+ $description: "Muted border — dark family (dusk/night).",
1247
+ filePath: "src/tokens/color.tokens.json",
1248
+ isSource: true,
1249
+ original: {
1250
+ $value: "{color.neutral.obsidian.600}",
1251
+ $type: "color",
1252
+ $description: "Muted border — dark family (dusk/night).",
1253
+ },
1254
+ name: "ColorDarkSurfaceBorderMuted",
1255
+ attributes: {
1256
+ category: "color",
1257
+ type: "dark",
1258
+ item: "surface",
1259
+ subitem: "border-muted",
1260
+ },
1261
+ path: ["color", "dark", "surface", "border-muted"],
1262
+ },
1263
+ },
1264
+ text: {
1265
+ secondary: {
1266
+ $value: "#8a95a8",
1267
+ $type: "color",
1268
+ $description:
1269
+ "Secondary text — dark family (dusk/night); 6.6:1 on night canvas.",
1270
+ filePath: "src/tokens/color.tokens.json",
1271
+ isSource: true,
1272
+ original: {
1273
+ $value: "{color.neutral.obsidian.400}",
1274
+ $type: "color",
1275
+ $description:
1276
+ "Secondary text — dark family (dusk/night); 6.6:1 on night canvas.",
1277
+ },
1278
+ name: "ColorDarkTextSecondary",
1279
+ attributes: {
1280
+ category: "color",
1281
+ type: "dark",
1282
+ item: "text",
1283
+ subitem: "secondary",
1284
+ },
1285
+ path: ["color", "dark", "text", "secondary"],
1286
+ },
1287
+ muted: {
1288
+ $value: "#4a5567",
1289
+ $type: "color",
1290
+ $description:
1291
+ "Muted text — dark family; de-emphasized, same sub-UI register as light muted (~2.3-2.6:1).",
1292
+ filePath: "src/tokens/color.tokens.json",
1293
+ isSource: true,
1294
+ original: {
1295
+ $value: "{color.neutral.obsidian.500}",
1296
+ $type: "color",
1297
+ $description:
1298
+ "Muted text — dark family; de-emphasized, same sub-UI register as light muted (~2.3-2.6:1).",
1299
+ },
1300
+ name: "ColorDarkTextMuted",
1301
+ attributes: {
1302
+ category: "color",
1303
+ type: "dark",
1304
+ item: "text",
1305
+ subitem: "muted",
1306
+ },
1307
+ path: ["color", "dark", "text", "muted"],
1308
+ },
1309
+ disabled: {
1310
+ $value: "#2a3142",
1311
+ $type: "color",
1312
+ $description:
1313
+ "Disabled text — dark family; low-contrast, deliberate (contrast-exempt).",
1314
+ filePath: "src/tokens/color.tokens.json",
1315
+ isSource: true,
1316
+ original: {
1317
+ $value: "{color.neutral.obsidian.600}",
1318
+ $type: "color",
1319
+ $description:
1320
+ "Disabled text — dark family; low-contrast, deliberate (contrast-exempt).",
1321
+ },
1322
+ name: "ColorDarkTextDisabled",
1323
+ attributes: {
1324
+ category: "color",
1325
+ type: "dark",
1326
+ item: "text",
1327
+ subitem: "disabled",
1328
+ },
1329
+ path: ["color", "dark", "text", "disabled"],
1330
+ },
1331
+ inverse: {
1332
+ $value: "#0b0f19",
1333
+ $type: "color",
1334
+ $description:
1335
+ "Text on light surfaces within a dark context — dark family. (0 current component uses.)",
1336
+ filePath: "src/tokens/color.tokens.json",
1337
+ isSource: true,
1338
+ original: {
1339
+ $value: "{color.neutral.mist.950}",
1340
+ $type: "color",
1341
+ $description:
1342
+ "Text on light surfaces within a dark context — dark family. (0 current component uses.)",
1343
+ },
1344
+ name: "ColorDarkTextInverse",
1345
+ attributes: {
1346
+ category: "color",
1347
+ type: "dark",
1348
+ item: "text",
1349
+ subitem: "inverse",
1350
+ },
1351
+ path: ["color", "dark", "text", "inverse"],
1352
+ },
1353
+ },
1354
+ },
1355
+ dusk: {
1356
+ surface: {
1357
+ raised: {
1358
+ $value: "#1f2638",
1359
+ $type: "color",
1360
+ $description:
1361
+ "Raised surface · cards — DUSK band only. The dusk canvas (#1a1a26, L≈0.011) is lighter than the shared dark family's raised (obsidian.850, L≈0.0067), which inverted elevation. Obsidian.700 (L≈0.0196) sits ABOVE the dusk canvas so cards read raised, while secondary text still clears AA (≈5.0:1).",
1362
+ filePath: "src/tokens/color.tokens.json",
1363
+ isSource: true,
1364
+ original: {
1365
+ $value: "{color.neutral.obsidian.700}",
1366
+ $type: "color",
1367
+ $description:
1368
+ "Raised surface · cards — DUSK band only. The dusk canvas (#1a1a26, L≈0.011) is lighter than the shared dark family's raised (obsidian.850, L≈0.0067), which inverted elevation. Obsidian.700 (L≈0.0196) sits ABOVE the dusk canvas so cards read raised, while secondary text still clears AA (≈5.0:1).",
1369
+ },
1370
+ name: "ColorDuskSurfaceRaised",
1371
+ attributes: {
1372
+ category: "color",
1373
+ type: "dusk",
1374
+ item: "surface",
1375
+ subitem: "raised",
1376
+ },
1377
+ path: ["color", "dusk", "surface", "raised"],
1378
+ },
1379
+ input: {
1380
+ $value: "#1f2638",
1381
+ $type: "color",
1382
+ $description:
1383
+ "Input / well — DUSK band only. Same tone as dusk raised (lifted above the dusk canvas); distinguished from cards by its border. Obsidian.700 keeps muted text at the ≈2.0:1 perceptible floor (obsidian.600 would drop it to ~1.7:1 and fail).",
1384
+ filePath: "src/tokens/color.tokens.json",
1385
+ isSource: true,
1386
+ original: {
1387
+ $value: "{color.neutral.obsidian.700}",
1388
+ $type: "color",
1389
+ $description:
1390
+ "Input / well — DUSK band only. Same tone as dusk raised (lifted above the dusk canvas); distinguished from cards by its border. Obsidian.700 keeps muted text at the ≈2.0:1 perceptible floor (obsidian.600 would drop it to ~1.7:1 and fail).",
1391
+ },
1392
+ name: "ColorDuskSurfaceInput",
1393
+ attributes: {
1394
+ category: "color",
1395
+ type: "dusk",
1396
+ item: "surface",
1397
+ subitem: "input",
1398
+ },
1399
+ path: ["color", "dusk", "surface", "input"],
1400
+ },
1401
+ border: {
1402
+ $value: "#4a5567",
1403
+ $type: "color",
1404
+ $description:
1405
+ "Border / divider — DUSK band only. Obsidian.500 (L≈0.089) gives inputs/cards a visible boundary on the dusk canvas (≈2.3:1) where the shared dark border (obsidian.700) would be ~invisible.",
1406
+ filePath: "src/tokens/color.tokens.json",
1407
+ isSource: true,
1408
+ original: {
1409
+ $value: "{color.neutral.obsidian.500}",
1410
+ $type: "color",
1411
+ $description:
1412
+ "Border / divider — DUSK band only. Obsidian.500 (L≈0.089) gives inputs/cards a visible boundary on the dusk canvas (≈2.3:1) where the shared dark border (obsidian.700) would be ~invisible.",
1413
+ },
1414
+ name: "ColorDuskSurfaceBorder",
1415
+ attributes: {
1416
+ category: "color",
1417
+ type: "dusk",
1418
+ item: "surface",
1419
+ subitem: "border",
1420
+ },
1421
+ path: ["color", "dusk", "surface", "border"],
1422
+ },
1423
+ "border-muted": {
1424
+ $value: "#2a3142",
1425
+ $type: "color",
1426
+ $description:
1427
+ "Muted border — DUSK band only; the softer divider above the dusk canvas.",
1428
+ filePath: "src/tokens/color.tokens.json",
1429
+ isSource: true,
1430
+ original: {
1431
+ $value: "{color.neutral.obsidian.600}",
1432
+ $type: "color",
1433
+ $description:
1434
+ "Muted border — DUSK band only; the softer divider above the dusk canvas.",
1435
+ },
1436
+ name: "ColorDuskSurfaceBorderMuted",
1437
+ attributes: {
1438
+ category: "color",
1439
+ type: "dusk",
1440
+ item: "surface",
1441
+ subitem: "border-muted",
1442
+ },
1443
+ path: ["color", "dusk", "surface", "border-muted"],
1444
+ },
1445
+ },
1446
+ },
1158
1447
  scrim: {
1159
1448
  light: {
1160
1449
  $value: "#0b0f1980",
@@ -1202,17 +1491,17 @@ module.exports = {
1202
1491
  action: {
1203
1492
  primary: {
1204
1493
  bg: {
1205
- $value: "#7c5cff",
1494
+ $value: "#7053e5",
1206
1495
  $type: "color",
1207
1496
  $description:
1208
- "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface.",
1497
+ "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. — AA-darkened (brand-strong, 5.04:1 with white).",
1209
1498
  filePath: "src/tokens/component.tokens.json",
1210
1499
  isSource: true,
1211
1500
  original: {
1212
- $value: "{color.brand.brand}",
1501
+ $value: "{color.brand.brand-strong}",
1213
1502
  $type: "color",
1214
1503
  $description:
1215
- "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface.",
1504
+ "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. — AA-darkened (brand-strong, 5.04:1 with white).",
1216
1505
  },
1217
1506
  name: "ColorActionPrimaryBg",
1218
1507
  attributes: {
@@ -1244,15 +1533,17 @@ module.exports = {
1244
1533
  path: ["color", "action", "primary", "fg"],
1245
1534
  },
1246
1535
  border: {
1247
- $value: "#7c5cff",
1536
+ $value: "#7053e5",
1248
1537
  $type: "color",
1249
- $description: "Primary action border — matches bg.",
1538
+ $description:
1539
+ "Primary action border — matches bg. — AA-darkened (brand-strong, 5.04:1 with white).",
1250
1540
  filePath: "src/tokens/component.tokens.json",
1251
1541
  isSource: true,
1252
1542
  original: {
1253
- $value: "{color.brand.brand}",
1543
+ $value: "{color.brand.brand-strong}",
1254
1544
  $type: "color",
1255
- $description: "Primary action border — matches bg.",
1545
+ $description:
1546
+ "Primary action border — matches bg. — AA-darkened (brand-strong, 5.04:1 with white).",
1256
1547
  },
1257
1548
  name: "ColorActionPrimaryBorder",
1258
1549
  attributes: {
@@ -1431,17 +1722,17 @@ module.exports = {
1431
1722
  },
1432
1723
  destructive: {
1433
1724
  bg: {
1434
- $value: "#ff4d4d",
1725
+ $value: "#be3939",
1435
1726
  $type: "color",
1436
1727
  $description:
1437
- "Destructive action background — Critical. A status color used for a destructive control; never the brand.",
1728
+ "Destructive action background — Critical. A status color used for a destructive control; never the brand. — AA-darkened (critical-strong, 5.34:1 with white).",
1438
1729
  filePath: "src/tokens/component.tokens.json",
1439
1730
  isSource: true,
1440
1731
  original: {
1441
- $value: "{color.semantic.critical}",
1732
+ $value: "{color.semantic.critical-strong}",
1442
1733
  $type: "color",
1443
1734
  $description:
1444
- "Destructive action background — Critical. A status color used for a destructive control; never the brand.",
1735
+ "Destructive action background — Critical. A status color used for a destructive control; never the brand. — AA-darkened (critical-strong, 5.34:1 with white).",
1445
1736
  },
1446
1737
  name: "ColorActionDestructiveBg",
1447
1738
  attributes: {
@@ -1473,15 +1764,17 @@ module.exports = {
1473
1764
  path: ["color", "action", "destructive", "fg"],
1474
1765
  },
1475
1766
  border: {
1476
- $value: "#ff4d4d",
1767
+ $value: "#be3939",
1477
1768
  $type: "color",
1478
- $description: "Destructive action border.",
1769
+ $description:
1770
+ "Destructive action border. — AA-darkened (critical-strong, 5.34:1 with white).",
1479
1771
  filePath: "src/tokens/component.tokens.json",
1480
1772
  isSource: true,
1481
1773
  original: {
1482
- $value: "{color.semantic.critical}",
1774
+ $value: "{color.semantic.critical-strong}",
1483
1775
  $type: "color",
1484
- $description: "Destructive action border.",
1776
+ $description:
1777
+ "Destructive action border. — AA-darkened (critical-strong, 5.34:1 with white).",
1485
1778
  },
1486
1779
  name: "ColorActionDestructiveBorder",
1487
1780
  attributes: {
@@ -1518,6 +1811,28 @@ module.exports = {
1518
1811
  },
1519
1812
  path: ["color", "status", "verified", "fg"],
1520
1813
  },
1814
+ "on-surface": {
1815
+ $value: "#007947",
1816
+ $type: "color",
1817
+ $description:
1818
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
1819
+ filePath: "src/tokens/component.tokens.json",
1820
+ isSource: true,
1821
+ original: {
1822
+ $value: "{color.semantic.verified-strong}",
1823
+ $type: "color",
1824
+ $description:
1825
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
1826
+ },
1827
+ name: "ColorStatusVerifiedOnSurface",
1828
+ attributes: {
1829
+ category: "color",
1830
+ type: "status",
1831
+ item: "verified",
1832
+ subitem: "on-surface",
1833
+ },
1834
+ path: ["color", "status", "verified", "on-surface"],
1835
+ },
1521
1836
  bg: {
1522
1837
  $value: "#e8ecf4",
1523
1838
  $type: "color",
@@ -1608,6 +1923,28 @@ module.exports = {
1608
1923
  },
1609
1924
  path: ["color", "status", "signal", "fg"],
1610
1925
  },
1926
+ "on-surface": {
1927
+ $value: "#346bad",
1928
+ $type: "color",
1929
+ $description:
1930
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
1931
+ filePath: "src/tokens/component.tokens.json",
1932
+ isSource: true,
1933
+ original: {
1934
+ $value: "{color.semantic.signal-strong}",
1935
+ $type: "color",
1936
+ $description:
1937
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
1938
+ },
1939
+ name: "ColorStatusSignalOnSurface",
1940
+ attributes: {
1941
+ category: "color",
1942
+ type: "status",
1943
+ item: "signal",
1944
+ subitem: "on-surface",
1945
+ },
1946
+ path: ["color", "status", "signal", "on-surface"],
1947
+ },
1611
1948
  bg: {
1612
1949
  $value: "#e8ecf4",
1613
1950
  $type: "color",
@@ -1696,6 +2033,28 @@ module.exports = {
1696
2033
  },
1697
2034
  path: ["color", "status", "caution", "fg"],
1698
2035
  },
2036
+ "on-surface": {
2037
+ $value: "#8e6014",
2038
+ $type: "color",
2039
+ $description:
2040
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
2041
+ filePath: "src/tokens/component.tokens.json",
2042
+ isSource: true,
2043
+ original: {
2044
+ $value: "{color.semantic.caution-strong}",
2045
+ $type: "color",
2046
+ $description:
2047
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
2048
+ },
2049
+ name: "ColorStatusCautionOnSurface",
2050
+ attributes: {
2051
+ category: "color",
2052
+ type: "status",
2053
+ item: "caution",
2054
+ subitem: "on-surface",
2055
+ },
2056
+ path: ["color", "status", "caution", "on-surface"],
2057
+ },
1699
2058
  bg: {
1700
2059
  $value: "#e8ecf4",
1701
2060
  $type: "color",
@@ -1784,6 +2143,28 @@ module.exports = {
1784
2143
  },
1785
2144
  path: ["color", "status", "critical", "fg"],
1786
2145
  },
2146
+ "on-surface": {
2147
+ $value: "#be3939",
2148
+ $type: "color",
2149
+ $description:
2150
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
2151
+ filePath: "src/tokens/component.tokens.json",
2152
+ isSource: true,
2153
+ original: {
2154
+ $value: "{color.semantic.critical-strong}",
2155
+ $type: "color",
2156
+ $description:
2157
+ "Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.",
2158
+ },
2159
+ name: "ColorStatusCriticalOnSurface",
2160
+ attributes: {
2161
+ category: "color",
2162
+ type: "status",
2163
+ item: "critical",
2164
+ subitem: "on-surface",
2165
+ },
2166
+ path: ["color", "status", "critical", "on-surface"],
2167
+ },
1787
2168
  bg: {
1788
2169
  $value: "#e8ecf4",
1789
2170
  $type: "color",
package/dist/tokens.json CHANGED
@@ -9,6 +9,7 @@
9
9
  "BreakpointXl": "80rem",
10
10
  "Breakpoint2xl": "96rem",
11
11
  "ColorBrandBrand": "#7c5cff",
12
+ "ColorBrandBrandStrong": "#7053e5",
12
13
  "ColorBrandBrandDeep": "#5b3ee8",
13
14
  "ColorNeutralObsidian300": "#c8d0de",
14
15
  "ColorNeutralObsidian400": "#8a95a8",
@@ -55,11 +56,23 @@
55
56
  "ColorTextDisabled": "#b0baca",
56
57
  "ColorTextInverse": "#fbfcfe",
57
58
  "ColorTextOnBrand": "#fbfcfe",
59
+ "ColorDarkSurfaceRaised": "#0f1320",
60
+ "ColorDarkSurfaceInput": "#161b2a",
61
+ "ColorDarkSurfaceBorder": "#1f2638",
62
+ "ColorDarkSurfaceBorderMuted": "#2a3142",
63
+ "ColorDarkTextSecondary": "#8a95a8",
64
+ "ColorDarkTextMuted": "#4a5567",
65
+ "ColorDarkTextDisabled": "#2a3142",
66
+ "ColorDarkTextInverse": "#0b0f19",
67
+ "ColorDuskSurfaceRaised": "#1f2638",
68
+ "ColorDuskSurfaceInput": "#1f2638",
69
+ "ColorDuskSurfaceBorder": "#4a5567",
70
+ "ColorDuskSurfaceBorderMuted": "#2a3142",
58
71
  "ColorScrimLight": "#0b0f1980",
59
72
  "ColorScrimDark": "#060912b3",
60
- "ColorActionPrimaryBg": "#7c5cff",
73
+ "ColorActionPrimaryBg": "#7053e5",
61
74
  "ColorActionPrimaryFg": "#fbfcfe",
62
- "ColorActionPrimaryBorder": "#7c5cff",
75
+ "ColorActionPrimaryBorder": "#7053e5",
63
76
  "ColorActionPrimaryBgHover": "#5b3ee8",
64
77
  "ColorActionPrimaryBgActive": "#5b3ee8",
65
78
  "ColorActionSecondaryBg": "#e8ecf4",
@@ -68,22 +81,26 @@
68
81
  "ColorActionSecondaryBgHover": "#d6dce8",
69
82
  "ColorActionGhostFg": "#0b0f19",
70
83
  "ColorActionGhostBgHover": "#e8ecf4",
71
- "ColorActionDestructiveBg": "#ff4d4d",
84
+ "ColorActionDestructiveBg": "#be3939",
72
85
  "ColorActionDestructiveFg": "#fbfcfe",
73
- "ColorActionDestructiveBorder": "#ff4d4d",
86
+ "ColorActionDestructiveBorder": "#be3939",
74
87
  "ColorStatusVerifiedFg": "#007947",
88
+ "ColorStatusVerifiedOnSurface": "#007947",
75
89
  "ColorStatusVerifiedBg": "#e8ecf4",
76
90
  "ColorStatusVerifiedBorder": "#007947",
77
91
  "ColorStatusVerifiedAccent": "#00d17a",
78
92
  "ColorStatusSignalFg": "#346bad",
93
+ "ColorStatusSignalOnSurface": "#346bad",
79
94
  "ColorStatusSignalBg": "#e8ecf4",
80
95
  "ColorStatusSignalBorder": "#346bad",
81
96
  "ColorStatusSignalAccent": "#4d9dff",
82
97
  "ColorStatusCautionFg": "#8e6014",
98
+ "ColorStatusCautionOnSurface": "#8e6014",
83
99
  "ColorStatusCautionBg": "#e8ecf4",
84
100
  "ColorStatusCautionBorder": "#8e6014",
85
101
  "ColorStatusCautionAccent": "#f5a623",
86
102
  "ColorStatusCriticalFg": "#be3939",
103
+ "ColorStatusCriticalOnSurface": "#be3939",
87
104
  "ColorStatusCriticalBg": "#e8ecf4",
88
105
  "ColorStatusCriticalBorder": "#be3939",
89
106
  "ColorStatusCriticalAccent": "#ff4d4d",
package/dist/tokens.mjs CHANGED
@@ -12,6 +12,7 @@ export const BreakpointLg = "64rem"; // Large breakpoint (1024px) — tablets la
12
12
  export const BreakpointXl = "80rem"; // Extra large breakpoint (1280px) — desktops
13
13
  export const Breakpoint2xl = "96rem"; // 2X large breakpoint (1536px) — wide desktops
14
14
  export const ColorBrandBrand = "#7c5cff"; // Sovereign Violet — the single brand anchor. Identity color; the logo seam and primary brand moments. Sits outside the traffic-light status register.
15
+ export const ColorBrandBrandStrong = "#7053e5"; // AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only.
15
16
  export const ColorBrandBrandDeep = "#5b3ee8"; // Companion to brand.brand — used on light surfaces where #7C5CFF fails WCAG 2.2 non-text contrast (>=3:1). Luminance shift only.
16
17
  export const ColorNeutralObsidian300 = "#c8d0de"; // Primary text on dark
17
18
  export const ColorNeutralObsidian400 = "#8a95a8"; // Secondary text
@@ -58,11 +59,23 @@ export const ColorTextMuted = "#8a95a8"; // Muted text — shared with obsidian.
58
59
  export const ColorTextDisabled = "#b0baca"; // Disabled text — low-contrast, deliberate. Aliases mist.400; downstream consumers may alternatively compose text.primary with state.opacity.disabled (0.38) for a different visual register.
59
60
  export const ColorTextInverse = "#fbfcfe"; // Text on dark surfaces (e.g. obsidian backdrop, dark scrim). Aliases mist.50 — the lightest neutral. Distinct from on-brand: inverse is for neutral-dark contexts; on-brand is reserved for brand backgrounds.
60
61
  export const ColorTextOnBrand = "#fbfcfe"; // Text on brand backgrounds (e.g. CTA buttons). Constant per brand discipline.
62
+ export const ColorDarkSurfaceRaised = "#0f1320"; // Raised surface · cards — dark family (dusk/night). Mirrors surface.raised in light.
63
+ export const ColorDarkSurfaceInput = "#161b2a"; // Input / well — dark family (dusk/night).
64
+ export const ColorDarkSurfaceBorder = "#1f2638"; // Border / divider — dark family (dusk/night).
65
+ export const ColorDarkSurfaceBorderMuted = "#2a3142"; // Muted border — dark family (dusk/night).
66
+ export const ColorDarkTextSecondary = "#8a95a8"; // Secondary text — dark family (dusk/night); 6.6:1 on night canvas.
67
+ export const ColorDarkTextMuted = "#4a5567"; // Muted text — dark family; de-emphasized, same sub-UI register as light muted (~2.3-2.6:1).
68
+ export const ColorDarkTextDisabled = "#2a3142"; // Disabled text — dark family; low-contrast, deliberate (contrast-exempt).
69
+ export const ColorDarkTextInverse = "#0b0f19"; // Text on light surfaces within a dark context — dark family. (0 current component uses.)
70
+ export const ColorDuskSurfaceRaised = "#1f2638"; // Raised surface · cards — DUSK band only. The dusk canvas (#1a1a26, L≈0.011) is lighter than the shared dark family's raised (obsidian.850, L≈0.0067), which inverted elevation. Obsidian.700 (L≈0.0196) sits ABOVE the dusk canvas so cards read raised, while secondary text still clears AA (≈5.0:1).
71
+ export const ColorDuskSurfaceInput = "#1f2638"; // Input / well — DUSK band only. Same tone as dusk raised (lifted above the dusk canvas); distinguished from cards by its border. Obsidian.700 keeps muted text at the ≈2.0:1 perceptible floor (obsidian.600 would drop it to ~1.7:1 and fail).
72
+ export const ColorDuskSurfaceBorder = "#4a5567"; // Border / divider — DUSK band only. Obsidian.500 (L≈0.089) gives inputs/cards a visible boundary on the dusk canvas (≈2.3:1) where the shared dark border (obsidian.700) would be ~invisible.
73
+ export const ColorDuskSurfaceBorderMuted = "#2a3142"; // Muted border — DUSK band only; the softer divider above the dusk canvas.
61
74
  export const ColorScrimLight = "#0b0f1980"; // Modal/sheet backdrop on light surfaces — obsidian-900 at 50% opacity (per BR-2 spec §4).
62
75
  export const ColorScrimDark = "#060912b3"; // Modal/sheet backdrop on dark surfaces — obsidian-950 at 70% opacity for stronger isolation.
63
- export const ColorActionPrimaryBg = "#7c5cff"; // Primary action background — Sovereign Violet. The single high-emphasis CTA per surface.
76
+ export const ColorActionPrimaryBg = "#7053e5"; // Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. — AA-darkened (brand-strong, 5.04:1 with white).
64
77
  export const ColorActionPrimaryFg = "#fbfcfe"; // Text/icon on a primary action.
65
- export const ColorActionPrimaryBorder = "#7c5cff"; // Primary action border — matches bg.
78
+ export const ColorActionPrimaryBorder = "#7053e5"; // Primary action border — matches bg. — AA-darkened (brand-strong, 5.04:1 with white).
66
79
  export const ColorActionPrimaryBgHover = "#5b3ee8"; // Primary action hover — deep companion.
67
80
  export const ColorActionPrimaryBgActive = "#5b3ee8"; // Primary action pressed/active.
68
81
  export const ColorActionSecondaryBg = "#e8ecf4"; // Secondary action background — neutral raised surface.
@@ -71,22 +84,26 @@ export const ColorActionSecondaryBorder = "#b0baca"; // Secondary action border.
71
84
  export const ColorActionSecondaryBgHover = "#d6dce8"; // Secondary action hover.
72
85
  export const ColorActionGhostFg = "#0b0f19"; // Ghost action text/icon — no fill until hover.
73
86
  export const ColorActionGhostBgHover = "#e8ecf4"; // Ghost action hover fill.
74
- export const ColorActionDestructiveBg = "#ff4d4d"; // Destructive action background — Critical. A status color used for a destructive control; never the brand.
87
+ export const ColorActionDestructiveBg = "#be3939"; // Destructive action background — Critical. A status color used for a destructive control; never the brand. — AA-darkened (critical-strong, 5.34:1 with white).
75
88
  export const ColorActionDestructiveFg = "#fbfcfe"; // Text/icon on a destructive action.
76
- export const ColorActionDestructiveBorder = "#ff4d4d"; // Destructive action border.
89
+ export const ColorActionDestructiveBorder = "#be3939"; // Destructive action border. — AA-darkened (critical-strong, 5.34:1 with white).
77
90
  export const ColorStatusVerifiedFg = "#007947"; // Verified status foreground — Verified Green darkened to WCAG AA (#007947, ≥4.5:1 on the chip bg). The in-product success state; never the brand.
91
+ export const ColorStatusVerifiedOnSurface = "#007947"; // Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.
78
92
  export const ColorStatusVerifiedBg = "#e8ecf4"; // Verified status chip background — neutral; color carried by fg/border (restraint over volume).
79
93
  export const ColorStatusVerifiedBorder = "#007947"; // Verified status border — AA-dark shade (≥3:1 non-text).
80
94
  export const ColorStatusVerifiedAccent = "#00d17a"; // Verified bright decorative accent (#00D17A) — for icons/fills where contrast is not a text/border requirement.
81
95
  export const ColorStatusSignalFg = "#346bad"; // Informational status foreground — Signal darkened to WCAG AA (#346BAD, ≥4.5:1 on the chip bg).
96
+ export const ColorStatusSignalOnSurface = "#346bad"; // Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.
82
97
  export const ColorStatusSignalBg = "#e8ecf4"; // Informational status chip background — neutral.
83
98
  export const ColorStatusSignalBorder = "#346bad"; // Informational status border — AA-dark shade (≥3:1 non-text).
84
99
  export const ColorStatusSignalAccent = "#4d9dff"; // Signal bright decorative accent (#4D9DFF) — for icons/fills.
85
100
  export const ColorStatusCautionFg = "#8e6014"; // Caution status foreground — Caution darkened to WCAG AA (#8E6014, ≥4.5:1 on the chip bg); pending / in-progress.
101
+ export const ColorStatusCautionOnSurface = "#8e6014"; // Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.
86
102
  export const ColorStatusCautionBg = "#e8ecf4"; // Caution status chip background — neutral.
87
103
  export const ColorStatusCautionBorder = "#8e6014"; // Caution status border — AA-dark shade (≥3:1 non-text).
88
104
  export const ColorStatusCautionAccent = "#f5a623"; // Caution bright decorative accent (#F5A623) — for icons/fills.
89
105
  export const ColorStatusCriticalFg = "#be3939"; // Critical status foreground — Critical darkened to WCAG AA (#BE3939, ≥4.5:1 on the chip bg); error / failure.
106
+ export const ColorStatusCriticalOnSurface = "#be3939"; // Status foreground for INLINE status text/icons on a theme surface — band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip.
90
107
  export const ColorStatusCriticalBg = "#e8ecf4"; // Critical status chip background — neutral.
91
108
  export const ColorStatusCriticalBorder = "#be3939"; // Critical status border — AA-dark shade (≥3:1 non-text).
92
109
  export const ColorStatusCriticalAccent = "#ff4d4d"; // Critical bright decorative accent (#FF4D4D) — for icons/fills.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdify/tokens",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Verdify design tokens — W3C DTCG sources with Tailwind v4 preset, CSS vars, JS/TS, and raw JSON outputs",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {
@@ -42,7 +42,7 @@
42
42
  "build:ase": "tsx scripts/build-ase.ts",
43
43
  "validate": "tsx scripts/validate.ts",
44
44
  "build": "pnpm run sync && pnpm run sync:print && pnpm run build:ase && pnpm run validate && tsx scripts/build.ts",
45
- "verify": "pnpm run build && git diff --exit-code src/",
45
+ "verify": "pnpm run build && git diff --exit-code src/ ../ui_flutter/lib/src/theme/",
46
46
  "test": "tsx scripts/test.ts"
47
47
  }
48
48
  }
@@ -6,6 +6,11 @@
6
6
  "$type": "color",
7
7
  "$description": "Sovereign Violet — the single brand anchor. Identity color; the logo seam and primary brand moments. Sits outside the traffic-light status register."
8
8
  },
9
+ "brand-strong": {
10
+ "$value": "#7053E5",
11
+ "$type": "color",
12
+ "$description": "AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only."
13
+ },
9
14
  "brand-deep": {
10
15
  "$value": "#5B3EE8",
11
16
  "$type": "color",
@@ -259,6 +264,76 @@
259
264
  "$description": "Text on brand backgrounds (e.g. CTA buttons). Constant per brand discipline."
260
265
  }
261
266
  },
267
+ "dark": {
268
+ "surface": {
269
+ "raised": {
270
+ "$value": "{color.neutral.obsidian.850}",
271
+ "$type": "color",
272
+ "$description": "Raised surface · cards — dark family (dusk/night). Mirrors surface.raised in light."
273
+ },
274
+ "input": {
275
+ "$value": "{color.neutral.obsidian.800}",
276
+ "$type": "color",
277
+ "$description": "Input / well — dark family (dusk/night)."
278
+ },
279
+ "border": {
280
+ "$value": "{color.neutral.obsidian.700}",
281
+ "$type": "color",
282
+ "$description": "Border / divider — dark family (dusk/night)."
283
+ },
284
+ "border-muted": {
285
+ "$value": "{color.neutral.obsidian.600}",
286
+ "$type": "color",
287
+ "$description": "Muted border — dark family (dusk/night)."
288
+ }
289
+ },
290
+ "text": {
291
+ "secondary": {
292
+ "$value": "{color.neutral.obsidian.400}",
293
+ "$type": "color",
294
+ "$description": "Secondary text — dark family (dusk/night); 6.6:1 on night canvas."
295
+ },
296
+ "muted": {
297
+ "$value": "{color.neutral.obsidian.500}",
298
+ "$type": "color",
299
+ "$description": "Muted text — dark family; de-emphasized, same sub-UI register as light muted (~2.3-2.6:1)."
300
+ },
301
+ "disabled": {
302
+ "$value": "{color.neutral.obsidian.600}",
303
+ "$type": "color",
304
+ "$description": "Disabled text — dark family; low-contrast, deliberate (contrast-exempt)."
305
+ },
306
+ "inverse": {
307
+ "$value": "{color.neutral.mist.950}",
308
+ "$type": "color",
309
+ "$description": "Text on light surfaces within a dark context — dark family. (0 current component uses.)"
310
+ }
311
+ }
312
+ },
313
+ "dusk": {
314
+ "surface": {
315
+ "raised": {
316
+ "$value": "{color.neutral.obsidian.700}",
317
+ "$type": "color",
318
+ "$description": "Raised surface · cards — DUSK band only. The dusk canvas (#1a1a26, L≈0.011) is lighter than the shared dark family's raised (obsidian.850, L≈0.0067), which inverted elevation. Obsidian.700 (L≈0.0196) sits ABOVE the dusk canvas so cards read raised, while secondary text still clears AA (≈5.0:1)."
319
+ },
320
+ "input": {
321
+ "$value": "{color.neutral.obsidian.700}",
322
+ "$type": "color",
323
+ "$description": "Input / well — DUSK band only. Same tone as dusk raised (lifted above the dusk canvas); distinguished from cards by its border. Obsidian.700 keeps muted text at the ≈2.0:1 perceptible floor (obsidian.600 would drop it to ~1.7:1 and fail)."
324
+ },
325
+ "border": {
326
+ "$value": "{color.neutral.obsidian.500}",
327
+ "$type": "color",
328
+ "$description": "Border / divider — DUSK band only. Obsidian.500 (L≈0.089) gives inputs/cards a visible boundary on the dusk canvas (≈2.3:1) where the shared dark border (obsidian.700) would be ~invisible."
329
+ },
330
+ "border-muted": {
331
+ "$value": "{color.neutral.obsidian.600}",
332
+ "$type": "color",
333
+ "$description": "Muted border — DUSK band only; the softer divider above the dusk canvas."
334
+ }
335
+ }
336
+ },
262
337
  "scrim": {
263
338
  "light": {
264
339
  "$value": "rgba(11, 15, 25, 0.5)",
@@ -2,9 +2,9 @@
2
2
  "color": {
3
3
  "action": {
4
4
  "primary": {
5
- "bg": { "$value": "{color.brand.brand}", "$type": "color", "$description": "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface." },
5
+ "bg": { "$value": "{color.brand.brand-strong}", "$type": "color", "$description": "Primary action background — Sovereign Violet. The single high-emphasis CTA per surface. — AA-darkened (brand-strong, 5.04:1 with white)." },
6
6
  "fg": { "$value": "{color.text.on-brand}", "$type": "color", "$description": "Text/icon on a primary action." },
7
- "border": { "$value": "{color.brand.brand}", "$type": "color", "$description": "Primary action border — matches bg." },
7
+ "border": { "$value": "{color.brand.brand-strong}", "$type": "color", "$description": "Primary action border — matches bg. — AA-darkened (brand-strong, 5.04:1 with white)." },
8
8
  "bg-hover": { "$value": "{color.brand.brand-deep}", "$type": "color", "$description": "Primary action hover — deep companion." },
9
9
  "bg-active": { "$value": "{color.brand.brand-deep}", "$type": "color", "$description": "Primary action pressed/active." }
10
10
  },
@@ -19,35 +19,39 @@
19
19
  "bg-hover": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Ghost action hover fill." }
20
20
  },
21
21
  "destructive": {
22
- "bg": { "$value": "{color.semantic.critical}", "$type": "color", "$description": "Destructive action background — Critical. A status color used for a destructive control; never the brand." },
22
+ "bg": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Destructive action background — Critical. A status color used for a destructive control; never the brand. — AA-darkened (critical-strong, 5.34:1 with white)." },
23
23
  "fg": { "$value": "{color.text.on-brand}", "$type": "color", "$description": "Text/icon on a destructive action." },
24
- "border": { "$value": "{color.semantic.critical}", "$type": "color", "$description": "Destructive action border." }
24
+ "border": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Destructive action border. — AA-darkened (critical-strong, 5.34:1 with white)." }
25
25
  }
26
26
  },
27
27
  "status": {
28
28
  "verified": {
29
- "fg": { "$value": "{color.semantic.verified-strong}", "$type": "color", "$description": "Verified status foreground — Verified Green darkened to WCAG AA (#007947, ≥4.5:1 on the chip bg). The in-product success state; never the brand." },
30
- "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Verified status chip backgroundneutral; color carried by fg/border (restraint over volume)." },
31
- "border": { "$value": "{color.semantic.verified-strong}", "$type": "color", "$description": "Verified status borderAA-dark shade (≥3:1 non-text)." },
32
- "accent": { "$value": "{color.semantic.verified}", "$type": "color", "$description": "Verified bright decorative accent (#00D17A) for icons/fills where contrast is not a text/border requirement." }
29
+ "fg": { "$value": "{color.semantic.verified-strong}", "$type": "color", "$description": "Verified status foreground — Verified Green darkened to WCAG AA (#007947, ≥4.5:1 on the chip bg). The in-product success state; never the brand." },
30
+ "on-surface": { "$value": "{color.semantic.verified-strong}", "$type": "color", "$description": "Status foreground for INLINE status text/icons on a theme surface band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip." },
31
+ "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Verified status chip background neutral; color carried by fg/border (restraint over volume)." },
32
+ "border": { "$value": "{color.semantic.verified-strong}", "$type": "color", "$description": "Verified status borderAA-dark shade (≥3:1 non-text)." },
33
+ "accent": { "$value": "{color.semantic.verified}", "$type": "color", "$description": "Verified bright decorative accent (#00D17A) — for icons/fills where contrast is not a text/border requirement." }
33
34
  },
34
35
  "signal": {
35
- "fg": { "$value": "{color.semantic.signal-strong}", "$type": "color", "$description": "Informational status foreground — Signal darkened to WCAG AA (#346BAD, ≥4.5:1 on the chip bg)." },
36
- "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Informational status chip backgroundneutral." },
37
- "border": { "$value": "{color.semantic.signal-strong}", "$type": "color", "$description": "Informational status borderAA-dark shade (≥3:1 non-text)." },
38
- "accent": { "$value": "{color.semantic.signal}", "$type": "color", "$description": "Signal bright decorative accent (#4D9DFF) for icons/fills." }
36
+ "fg": { "$value": "{color.semantic.signal-strong}", "$type": "color", "$description": "Informational status foreground — Signal darkened to WCAG AA (#346BAD, ≥4.5:1 on the chip bg)." },
37
+ "on-surface": { "$value": "{color.semantic.signal-strong}", "$type": "color", "$description": "Status foreground for INLINE status text/icons on a theme surface band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip." },
38
+ "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Informational status chip background neutral." },
39
+ "border": { "$value": "{color.semantic.signal-strong}", "$type": "color", "$description": "Informational status border AA-dark shade (≥3:1 non-text)." },
40
+ "accent": { "$value": "{color.semantic.signal}", "$type": "color", "$description": "Signal bright decorative accent (#4D9DFF) — for icons/fills." }
39
41
  },
40
42
  "caution": {
41
- "fg": { "$value": "{color.semantic.caution-strong}", "$type": "color", "$description": "Caution status foreground — Caution darkened to WCAG AA (#8E6014, ≥4.5:1 on the chip bg); pending / in-progress." },
42
- "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Caution status chip backgroundneutral." },
43
- "border": { "$value": "{color.semantic.caution-strong}", "$type": "color", "$description": "Caution status borderAA-dark shade (≥3:1 non-text)." },
44
- "accent": { "$value": "{color.semantic.caution}", "$type": "color", "$description": "Caution bright decorative accent (#F5A623) for icons/fills." }
43
+ "fg": { "$value": "{color.semantic.caution-strong}", "$type": "color", "$description": "Caution status foreground — Caution darkened to WCAG AA (#8E6014, ≥4.5:1 on the chip bg); pending / in-progress." },
44
+ "on-surface": { "$value": "{color.semantic.caution-strong}", "$type": "color", "$description": "Status foreground for INLINE status text/icons on a theme surface band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip." },
45
+ "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Caution status chip background neutral." },
46
+ "border": { "$value": "{color.semantic.caution-strong}", "$type": "color", "$description": "Caution status border AA-dark shade (≥3:1 non-text)." },
47
+ "accent": { "$value": "{color.semantic.caution}", "$type": "color", "$description": "Caution bright decorative accent (#F5A623) — for icons/fills." }
45
48
  },
46
49
  "critical": {
47
- "fg": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Critical status foreground — Critical darkened to WCAG AA (#BE3939, ≥4.5:1 on the chip bg); error / failure." },
48
- "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Critical status chip backgroundneutral." },
49
- "border": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Critical status borderAA-dark shade (≥3:1 non-text)." },
50
- "accent": { "$value": "{color.semantic.critical}", "$type": "color", "$description": "Critical bright decorative accent (#FF4D4D) for icons/fills." }
50
+ "fg": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Critical status foreground — Critical darkened to WCAG AA (#BE3939, ≥4.5:1 on the chip bg); error / failure." },
51
+ "on-surface": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Status foreground for INLINE status text/icons on a theme surface band-aware: -strong on light bands, bright base on dusk/night (AA on dark). Distinct from .fg, which is for the always-light status chip." },
52
+ "bg": { "$value": "{color.surface.raised}", "$type": "color", "$description": "Critical status chip background neutral." },
53
+ "border": { "$value": "{color.semantic.critical-strong}", "$type": "color", "$description": "Critical status border AA-dark shade (≥3:1 non-text)." },
54
+ "accent": { "$value": "{color.semantic.critical}", "$type": "color", "$description": "Critical bright decorative accent (#FF4D4D) — for icons/fills." }
51
55
  }
52
56
  },
53
57
  "border": {
@@ -13,6 +13,17 @@
13
13
  }
14
14
  }
15
15
  },
16
+ "brand-strong": {
17
+ "$value": "#7053E5",
18
+ "$type": "color",
19
+ "$description": "AA-darkened companion to brand.brand — the action-primary fill where white text on #7C5CFF fails WCAG 2.2 AA (4.23:1); #7053E5 clears 5.04:1. Luminance shift only.",
20
+ "$extensions": {
21
+ "com.verdify.print": {
22
+ "cmyk": "51,64,0,10",
23
+ "pantone": "PANTONE 2725 C"
24
+ }
25
+ }
26
+ },
16
27
  "brand-deep": {
17
28
  "$value": "#5B3EE8",
18
29
  "$type": "color",
Binary file