@hotelfriendag/design-tokens 0.3.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/LICENSE +21 -0
- package/README.md +558 -0
- package/README.uk.md +377 -0
- package/RFC-0001-cross-project-design-system.md +273 -0
- package/RFC-0002-semantic-tier-naming.md +296 -0
- package/UI_DESIGN.md +608 -0
- package/ai-rules/CLAUDE.md +80 -0
- package/ai-rules/cursorrules.template +39 -0
- package/ai-rules/github-copilot-instructions.md +45 -0
- package/ai-rules/system-prompt-compact.md +43 -0
- package/components.html +3018 -0
- package/generate-tokens.cjs +665 -0
- package/package.json +98 -0
- package/portal-audit.html +2306 -0
- package/pre-built/_tokens.scss +138 -0
- package/pre-built/components.css +515 -0
- package/pre-built/shadcn-tokens.css +67 -0
- package/pre-built/status.css +51 -0
- package/pre-built/stylelint-design-system.cjs +69 -0
- package/pre-built/tailwind.additive.css +158 -0
- package/pre-built/tailwind.css +158 -0
- package/pre-built/tailwind.preset.js +207 -0
- package/pre-built/tokens.css +185 -0
- package/pre-built/tokens.d.ts +240 -0
- package/pre-built/tokens.js +243 -0
- package/pre-built/tokens.ts +240 -0
- package/scripts/integration-smoke.sh +91 -0
- package/scripts/pre-commit.sh +55 -0
- package/scripts/validate-tokens.cjs +113 -0
- package/states-canonical.json +240 -0
- package/states.json +2950 -0
- package/status-map.json +47 -0
- package/tokens.figma.json +230 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// HotelFriend design tokens — CommonJS module
|
|
2
|
+
// Generated from docs/tokens.figma.json — do NOT edit by hand.
|
|
3
|
+
//
|
|
4
|
+
// Works with both `require("@hotelfriendag/design-tokens").tokens` and
|
|
5
|
+
// ESM `import { tokens } from "@hotelfriendag/design-tokens"` via Node CJS-ESM interop.
|
|
6
|
+
|
|
7
|
+
const tokens = {
|
|
8
|
+
"color": {
|
|
9
|
+
"blue": {
|
|
10
|
+
"50": "#E9F6FC",
|
|
11
|
+
"100": "#EFF6FF",
|
|
12
|
+
"500": "#24AFE8",
|
|
13
|
+
"600": "#149AD1"
|
|
14
|
+
},
|
|
15
|
+
"gray": {
|
|
16
|
+
"25": "#FBFBFC",
|
|
17
|
+
"50": "#F6F7FB",
|
|
18
|
+
"100": "#F1F3F6",
|
|
19
|
+
"200": "#E4E8EF",
|
|
20
|
+
"300": "#D1D6DD",
|
|
21
|
+
"400": "#AEBCCF",
|
|
22
|
+
"500": "#99A1B7",
|
|
23
|
+
"550": "#7E8EA6",
|
|
24
|
+
"600": "#50627E",
|
|
25
|
+
"700": "#485B78",
|
|
26
|
+
"800": "#4B5675",
|
|
27
|
+
"900": "#2B2B2B",
|
|
28
|
+
"950": "#252F4A"
|
|
29
|
+
},
|
|
30
|
+
"green": {
|
|
31
|
+
"500": "#59B59D"
|
|
32
|
+
},
|
|
33
|
+
"amber": {
|
|
34
|
+
"400": "#FFBD5A",
|
|
35
|
+
"600": "#FFC900"
|
|
36
|
+
},
|
|
37
|
+
"red": {
|
|
38
|
+
"400": "#EA6565",
|
|
39
|
+
"500": "#FB5A56",
|
|
40
|
+
"700": "#D9534F"
|
|
41
|
+
},
|
|
42
|
+
"orange": {
|
|
43
|
+
"500": "#F87921",
|
|
44
|
+
"700": "#A55505"
|
|
45
|
+
},
|
|
46
|
+
"violet": {
|
|
47
|
+
"500": "#5761D8"
|
|
48
|
+
},
|
|
49
|
+
"slate": {
|
|
50
|
+
"500": "#7F8FA4"
|
|
51
|
+
},
|
|
52
|
+
"olive": {
|
|
53
|
+
"700": "#5B7A02"
|
|
54
|
+
},
|
|
55
|
+
"white": "#FFFFFF",
|
|
56
|
+
"black": "#000000",
|
|
57
|
+
"accent": {
|
|
58
|
+
"default": "{primitive.color.blue.500}",
|
|
59
|
+
"hover": "{primitive.color.blue.600}",
|
|
60
|
+
"subtle": "{primitive.color.blue.50}",
|
|
61
|
+
"subtler": "{primitive.color.blue.100}"
|
|
62
|
+
},
|
|
63
|
+
"on-accent": "{primitive.color.white}",
|
|
64
|
+
"bg": {
|
|
65
|
+
"page": "{primitive.color.gray.25}",
|
|
66
|
+
"section": "{primitive.color.gray.50}",
|
|
67
|
+
"muted": "{primitive.color.gray.100}",
|
|
68
|
+
"surface": "{primitive.color.white}"
|
|
69
|
+
},
|
|
70
|
+
"fg": {
|
|
71
|
+
"default": "{primitive.color.gray.900}",
|
|
72
|
+
"muted": "{primitive.color.gray.800}",
|
|
73
|
+
"subtle": "{primitive.color.gray.550}",
|
|
74
|
+
"faint": "{primitive.color.gray.400}"
|
|
75
|
+
},
|
|
76
|
+
"border": {
|
|
77
|
+
"default": "{primitive.color.gray.300}",
|
|
78
|
+
"subtle": "{primitive.color.gray.200}",
|
|
79
|
+
"strong": "{primitive.color.gray.400}"
|
|
80
|
+
},
|
|
81
|
+
"tab": {
|
|
82
|
+
"fg-inactive": "{primitive.color.gray.700}",
|
|
83
|
+
"count-fg": "{primitive.color.gray.700}"
|
|
84
|
+
},
|
|
85
|
+
"pagination": {
|
|
86
|
+
"fg-inactive": "{primitive.color.gray.700}",
|
|
87
|
+
"fg-active": "{primitive.color.gray.950}"
|
|
88
|
+
},
|
|
89
|
+
"input": {
|
|
90
|
+
"border": "#DBDFE9"
|
|
91
|
+
},
|
|
92
|
+
"menu": {
|
|
93
|
+
"bg-hover": "#F5F5F5"
|
|
94
|
+
},
|
|
95
|
+
"status": {
|
|
96
|
+
"success": "{primitive.color.green.500}",
|
|
97
|
+
"success-bg": "rgba(89,181,157,0.15)",
|
|
98
|
+
"warning": "{primitive.color.amber.400}",
|
|
99
|
+
"warning-bg": "rgba(255,189,90,0.15)",
|
|
100
|
+
"warning-strong": "{primitive.color.amber.600}",
|
|
101
|
+
"warning-strong-bg": "rgba(255,201,0,0.15)",
|
|
102
|
+
"error": "{primitive.color.red.400}",
|
|
103
|
+
"error-bg": "rgba(234,101,101,0.15)",
|
|
104
|
+
"error-strong": "{primitive.color.red.700}",
|
|
105
|
+
"error-alt": "{primitive.color.red.500}",
|
|
106
|
+
"info": "{semantic.color.accent.default}",
|
|
107
|
+
"info-bg": "rgba(36,175,232,0.15)",
|
|
108
|
+
"cancel": "{primitive.color.slate.500}",
|
|
109
|
+
"cancel-bg": "rgba(127,143,164,0.15)",
|
|
110
|
+
"coral": "{primitive.color.orange.500}",
|
|
111
|
+
"coral-bg": "rgba(248,121,33,0.15)",
|
|
112
|
+
"violet": "{primitive.color.violet.500}",
|
|
113
|
+
"violet-bg": "rgba(87,97,216,0.15)",
|
|
114
|
+
"olive": "{primitive.color.olive.700}",
|
|
115
|
+
"olive-bg": "rgba(91,122,2,0.15)",
|
|
116
|
+
"orange-deep": "{primitive.color.orange.700}",
|
|
117
|
+
"orange-deep-bg": "rgba(165,85,5,0.15)"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"fontFamily": {
|
|
121
|
+
"primary": "Roboto"
|
|
122
|
+
},
|
|
123
|
+
"fontWeight": {
|
|
124
|
+
"regular": "400",
|
|
125
|
+
"medium": "500",
|
|
126
|
+
"semibold": "600"
|
|
127
|
+
},
|
|
128
|
+
"fontSize": {
|
|
129
|
+
"xs": "11px",
|
|
130
|
+
"sm": "13px",
|
|
131
|
+
"base": "14px",
|
|
132
|
+
"md": "15px",
|
|
133
|
+
"lg": "16px",
|
|
134
|
+
"xl": "18px",
|
|
135
|
+
"2xl": "20px",
|
|
136
|
+
"h2": "24px",
|
|
137
|
+
"page": "26px",
|
|
138
|
+
"hero": "30px"
|
|
139
|
+
},
|
|
140
|
+
"lineHeight": {
|
|
141
|
+
"headings": "1.2",
|
|
142
|
+
"body": "1.5",
|
|
143
|
+
"tight": "1"
|
|
144
|
+
},
|
|
145
|
+
"typography": {
|
|
146
|
+
"pageTitle": {
|
|
147
|
+
"fontFamily": "{fontFamily.primary}",
|
|
148
|
+
"fontWeight": "{fontWeight.semibold}",
|
|
149
|
+
"fontSize": "{fontSize.page}",
|
|
150
|
+
"lineHeight": "{lineHeight.headings}"
|
|
151
|
+
},
|
|
152
|
+
"btn": {
|
|
153
|
+
"fontFamily": "{fontFamily.primary}",
|
|
154
|
+
"fontWeight": "{fontWeight.semibold}",
|
|
155
|
+
"fontSize": "{fontSize.md}",
|
|
156
|
+
"lineHeight": "{lineHeight.body}"
|
|
157
|
+
},
|
|
158
|
+
"body": {
|
|
159
|
+
"fontFamily": "{fontFamily.primary}",
|
|
160
|
+
"fontWeight": "{fontWeight.regular}",
|
|
161
|
+
"fontSize": "{fontSize.base}",
|
|
162
|
+
"lineHeight": "{lineHeight.body}"
|
|
163
|
+
},
|
|
164
|
+
"label": {
|
|
165
|
+
"fontFamily": "{fontFamily.primary}",
|
|
166
|
+
"fontWeight": "{fontWeight.medium}",
|
|
167
|
+
"fontSize": "{fontSize.base}",
|
|
168
|
+
"lineHeight": "{lineHeight.body}"
|
|
169
|
+
},
|
|
170
|
+
"gridHeader": {
|
|
171
|
+
"fontFamily": "{fontFamily.primary}",
|
|
172
|
+
"fontWeight": "{fontWeight.medium}",
|
|
173
|
+
"fontSize": "{fontSize.sm}",
|
|
174
|
+
"lineHeight": "{lineHeight.body}"
|
|
175
|
+
},
|
|
176
|
+
"tagLabel": {
|
|
177
|
+
"fontFamily": "{fontFamily.primary}",
|
|
178
|
+
"fontWeight": "{fontWeight.medium}",
|
|
179
|
+
"fontSize": "{fontSize.xs}",
|
|
180
|
+
"lineHeight": "{lineHeight.headings}"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"spacing": {
|
|
184
|
+
"0": "0px",
|
|
185
|
+
"1": "4px",
|
|
186
|
+
"2": "8px",
|
|
187
|
+
"3": "12px",
|
|
188
|
+
"4": "16px",
|
|
189
|
+
"5": "20px",
|
|
190
|
+
"6": "24px",
|
|
191
|
+
"7": "30px",
|
|
192
|
+
"8": "32px"
|
|
193
|
+
},
|
|
194
|
+
"radius": {
|
|
195
|
+
"sm": "6px",
|
|
196
|
+
"md": "8px",
|
|
197
|
+
"lg": "9px",
|
|
198
|
+
"xl": "12px",
|
|
199
|
+
"pill": "99px"
|
|
200
|
+
},
|
|
201
|
+
"shadow": {
|
|
202
|
+
"default": "0px 1px 8px 0px rgba(0,0,0,0.1)",
|
|
203
|
+
"subtle": "0px 2px 4px 0px rgba(0,0,0,0.05)",
|
|
204
|
+
"wrapper": "0px 3px 4px 0px rgba(0,0,0,0.03)",
|
|
205
|
+
"card": "0px 12px 24px 0px rgba(26,26,30,0.06)",
|
|
206
|
+
"modal": "0px 6px 18px 0px rgba(0,0,0,0.1)",
|
|
207
|
+
"outline": "0px 1px 2px 0px rgba(72,91,120,0.18)",
|
|
208
|
+
"hover": "0px 2px 3px 0px rgba(0,0,0,0.06)"
|
|
209
|
+
},
|
|
210
|
+
"opacity": {
|
|
211
|
+
"disabled": "0.6",
|
|
212
|
+
"tint": "0.15"
|
|
213
|
+
},
|
|
214
|
+
"size": {
|
|
215
|
+
"sidebarExpanded": "215px",
|
|
216
|
+
"sidebarCollapsed": "80px",
|
|
217
|
+
"headerHeight": "60px",
|
|
218
|
+
"contentMax": "1440px",
|
|
219
|
+
"btnDefault": "40px",
|
|
220
|
+
"btnSm": "32px",
|
|
221
|
+
"btnSearch": "38px",
|
|
222
|
+
"inputDefault": "39px",
|
|
223
|
+
"tapTarget": "44px"
|
|
224
|
+
},
|
|
225
|
+
"zIndex": {
|
|
226
|
+
"sidebar": "1000",
|
|
227
|
+
"dropdown": "1001",
|
|
228
|
+
"datepicker": "3000",
|
|
229
|
+
"stickyTopbar": "4000",
|
|
230
|
+
"modalBackdrop": "10050",
|
|
231
|
+
"modalDialog": "10051",
|
|
232
|
+
"preloader": "99999",
|
|
233
|
+
"topmostOverlay": "1000001"
|
|
234
|
+
},
|
|
235
|
+
"motion": {
|
|
236
|
+
"fast": "0.1s",
|
|
237
|
+
"default": "0.2s ease-in-out",
|
|
238
|
+
"slow": "0.3s",
|
|
239
|
+
"bouncy": "0.4s cubic-bezier(0.88, -0.99, 0, 1.81)"
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
module.exports = { tokens };
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// HotelFriend design tokens — TypeScript const
|
|
2
|
+
// Generated from docs/tokens.figma.json — do NOT edit by hand.
|
|
3
|
+
|
|
4
|
+
export const tokens = {
|
|
5
|
+
"color": {
|
|
6
|
+
"blue": {
|
|
7
|
+
"50": "#E9F6FC",
|
|
8
|
+
"100": "#EFF6FF",
|
|
9
|
+
"500": "#24AFE8",
|
|
10
|
+
"600": "#149AD1"
|
|
11
|
+
},
|
|
12
|
+
"gray": {
|
|
13
|
+
"25": "#FBFBFC",
|
|
14
|
+
"50": "#F6F7FB",
|
|
15
|
+
"100": "#F1F3F6",
|
|
16
|
+
"200": "#E4E8EF",
|
|
17
|
+
"300": "#D1D6DD",
|
|
18
|
+
"400": "#AEBCCF",
|
|
19
|
+
"500": "#99A1B7",
|
|
20
|
+
"550": "#7E8EA6",
|
|
21
|
+
"600": "#50627E",
|
|
22
|
+
"700": "#485B78",
|
|
23
|
+
"800": "#4B5675",
|
|
24
|
+
"900": "#2B2B2B",
|
|
25
|
+
"950": "#252F4A"
|
|
26
|
+
},
|
|
27
|
+
"green": {
|
|
28
|
+
"500": "#59B59D"
|
|
29
|
+
},
|
|
30
|
+
"amber": {
|
|
31
|
+
"400": "#FFBD5A",
|
|
32
|
+
"600": "#FFC900"
|
|
33
|
+
},
|
|
34
|
+
"red": {
|
|
35
|
+
"400": "#EA6565",
|
|
36
|
+
"500": "#FB5A56",
|
|
37
|
+
"700": "#D9534F"
|
|
38
|
+
},
|
|
39
|
+
"orange": {
|
|
40
|
+
"500": "#F87921",
|
|
41
|
+
"700": "#A55505"
|
|
42
|
+
},
|
|
43
|
+
"violet": {
|
|
44
|
+
"500": "#5761D8"
|
|
45
|
+
},
|
|
46
|
+
"slate": {
|
|
47
|
+
"500": "#7F8FA4"
|
|
48
|
+
},
|
|
49
|
+
"olive": {
|
|
50
|
+
"700": "#5B7A02"
|
|
51
|
+
},
|
|
52
|
+
"white": "#FFFFFF",
|
|
53
|
+
"black": "#000000",
|
|
54
|
+
"accent": {
|
|
55
|
+
"default": "{primitive.color.blue.500}",
|
|
56
|
+
"hover": "{primitive.color.blue.600}",
|
|
57
|
+
"subtle": "{primitive.color.blue.50}",
|
|
58
|
+
"subtler": "{primitive.color.blue.100}"
|
|
59
|
+
},
|
|
60
|
+
"on-accent": "{primitive.color.white}",
|
|
61
|
+
"bg": {
|
|
62
|
+
"page": "{primitive.color.gray.25}",
|
|
63
|
+
"section": "{primitive.color.gray.50}",
|
|
64
|
+
"muted": "{primitive.color.gray.100}",
|
|
65
|
+
"surface": "{primitive.color.white}"
|
|
66
|
+
},
|
|
67
|
+
"fg": {
|
|
68
|
+
"default": "{primitive.color.gray.900}",
|
|
69
|
+
"muted": "{primitive.color.gray.800}",
|
|
70
|
+
"subtle": "{primitive.color.gray.550}",
|
|
71
|
+
"faint": "{primitive.color.gray.400}"
|
|
72
|
+
},
|
|
73
|
+
"border": {
|
|
74
|
+
"default": "{primitive.color.gray.300}",
|
|
75
|
+
"subtle": "{primitive.color.gray.200}",
|
|
76
|
+
"strong": "{primitive.color.gray.400}"
|
|
77
|
+
},
|
|
78
|
+
"tab": {
|
|
79
|
+
"fg-inactive": "{primitive.color.gray.700}",
|
|
80
|
+
"count-fg": "{primitive.color.gray.700}"
|
|
81
|
+
},
|
|
82
|
+
"pagination": {
|
|
83
|
+
"fg-inactive": "{primitive.color.gray.700}",
|
|
84
|
+
"fg-active": "{primitive.color.gray.950}"
|
|
85
|
+
},
|
|
86
|
+
"input": {
|
|
87
|
+
"border": "#DBDFE9"
|
|
88
|
+
},
|
|
89
|
+
"menu": {
|
|
90
|
+
"bg-hover": "#F5F5F5"
|
|
91
|
+
},
|
|
92
|
+
"status": {
|
|
93
|
+
"success": "{primitive.color.green.500}",
|
|
94
|
+
"success-bg": "rgba(89,181,157,0.15)",
|
|
95
|
+
"warning": "{primitive.color.amber.400}",
|
|
96
|
+
"warning-bg": "rgba(255,189,90,0.15)",
|
|
97
|
+
"warning-strong": "{primitive.color.amber.600}",
|
|
98
|
+
"warning-strong-bg": "rgba(255,201,0,0.15)",
|
|
99
|
+
"error": "{primitive.color.red.400}",
|
|
100
|
+
"error-bg": "rgba(234,101,101,0.15)",
|
|
101
|
+
"error-strong": "{primitive.color.red.700}",
|
|
102
|
+
"error-alt": "{primitive.color.red.500}",
|
|
103
|
+
"info": "{semantic.color.accent.default}",
|
|
104
|
+
"info-bg": "rgba(36,175,232,0.15)",
|
|
105
|
+
"cancel": "{primitive.color.slate.500}",
|
|
106
|
+
"cancel-bg": "rgba(127,143,164,0.15)",
|
|
107
|
+
"coral": "{primitive.color.orange.500}",
|
|
108
|
+
"coral-bg": "rgba(248,121,33,0.15)",
|
|
109
|
+
"violet": "{primitive.color.violet.500}",
|
|
110
|
+
"violet-bg": "rgba(87,97,216,0.15)",
|
|
111
|
+
"olive": "{primitive.color.olive.700}",
|
|
112
|
+
"olive-bg": "rgba(91,122,2,0.15)",
|
|
113
|
+
"orange-deep": "{primitive.color.orange.700}",
|
|
114
|
+
"orange-deep-bg": "rgba(165,85,5,0.15)"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"fontFamily": {
|
|
118
|
+
"primary": "Roboto"
|
|
119
|
+
},
|
|
120
|
+
"fontWeight": {
|
|
121
|
+
"regular": "400",
|
|
122
|
+
"medium": "500",
|
|
123
|
+
"semibold": "600"
|
|
124
|
+
},
|
|
125
|
+
"fontSize": {
|
|
126
|
+
"xs": "11px",
|
|
127
|
+
"sm": "13px",
|
|
128
|
+
"base": "14px",
|
|
129
|
+
"md": "15px",
|
|
130
|
+
"lg": "16px",
|
|
131
|
+
"xl": "18px",
|
|
132
|
+
"2xl": "20px",
|
|
133
|
+
"h2": "24px",
|
|
134
|
+
"page": "26px",
|
|
135
|
+
"hero": "30px"
|
|
136
|
+
},
|
|
137
|
+
"lineHeight": {
|
|
138
|
+
"headings": "1.2",
|
|
139
|
+
"body": "1.5",
|
|
140
|
+
"tight": "1"
|
|
141
|
+
},
|
|
142
|
+
"typography": {
|
|
143
|
+
"pageTitle": {
|
|
144
|
+
"fontFamily": "{fontFamily.primary}",
|
|
145
|
+
"fontWeight": "{fontWeight.semibold}",
|
|
146
|
+
"fontSize": "{fontSize.page}",
|
|
147
|
+
"lineHeight": "{lineHeight.headings}"
|
|
148
|
+
},
|
|
149
|
+
"btn": {
|
|
150
|
+
"fontFamily": "{fontFamily.primary}",
|
|
151
|
+
"fontWeight": "{fontWeight.semibold}",
|
|
152
|
+
"fontSize": "{fontSize.md}",
|
|
153
|
+
"lineHeight": "{lineHeight.body}"
|
|
154
|
+
},
|
|
155
|
+
"body": {
|
|
156
|
+
"fontFamily": "{fontFamily.primary}",
|
|
157
|
+
"fontWeight": "{fontWeight.regular}",
|
|
158
|
+
"fontSize": "{fontSize.base}",
|
|
159
|
+
"lineHeight": "{lineHeight.body}"
|
|
160
|
+
},
|
|
161
|
+
"label": {
|
|
162
|
+
"fontFamily": "{fontFamily.primary}",
|
|
163
|
+
"fontWeight": "{fontWeight.medium}",
|
|
164
|
+
"fontSize": "{fontSize.base}",
|
|
165
|
+
"lineHeight": "{lineHeight.body}"
|
|
166
|
+
},
|
|
167
|
+
"gridHeader": {
|
|
168
|
+
"fontFamily": "{fontFamily.primary}",
|
|
169
|
+
"fontWeight": "{fontWeight.medium}",
|
|
170
|
+
"fontSize": "{fontSize.sm}",
|
|
171
|
+
"lineHeight": "{lineHeight.body}"
|
|
172
|
+
},
|
|
173
|
+
"tagLabel": {
|
|
174
|
+
"fontFamily": "{fontFamily.primary}",
|
|
175
|
+
"fontWeight": "{fontWeight.medium}",
|
|
176
|
+
"fontSize": "{fontSize.xs}",
|
|
177
|
+
"lineHeight": "{lineHeight.headings}"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"spacing": {
|
|
181
|
+
"0": "0px",
|
|
182
|
+
"1": "4px",
|
|
183
|
+
"2": "8px",
|
|
184
|
+
"3": "12px",
|
|
185
|
+
"4": "16px",
|
|
186
|
+
"5": "20px",
|
|
187
|
+
"6": "24px",
|
|
188
|
+
"7": "30px",
|
|
189
|
+
"8": "32px"
|
|
190
|
+
},
|
|
191
|
+
"radius": {
|
|
192
|
+
"sm": "6px",
|
|
193
|
+
"md": "8px",
|
|
194
|
+
"lg": "9px",
|
|
195
|
+
"xl": "12px",
|
|
196
|
+
"pill": "99px"
|
|
197
|
+
},
|
|
198
|
+
"shadow": {
|
|
199
|
+
"default": "0px 1px 8px 0px rgba(0,0,0,0.1)",
|
|
200
|
+
"subtle": "0px 2px 4px 0px rgba(0,0,0,0.05)",
|
|
201
|
+
"wrapper": "0px 3px 4px 0px rgba(0,0,0,0.03)",
|
|
202
|
+
"card": "0px 12px 24px 0px rgba(26,26,30,0.06)",
|
|
203
|
+
"modal": "0px 6px 18px 0px rgba(0,0,0,0.1)",
|
|
204
|
+
"outline": "0px 1px 2px 0px rgba(72,91,120,0.18)",
|
|
205
|
+
"hover": "0px 2px 3px 0px rgba(0,0,0,0.06)"
|
|
206
|
+
},
|
|
207
|
+
"opacity": {
|
|
208
|
+
"disabled": "0.6",
|
|
209
|
+
"tint": "0.15"
|
|
210
|
+
},
|
|
211
|
+
"size": {
|
|
212
|
+
"sidebarExpanded": "215px",
|
|
213
|
+
"sidebarCollapsed": "80px",
|
|
214
|
+
"headerHeight": "60px",
|
|
215
|
+
"contentMax": "1440px",
|
|
216
|
+
"btnDefault": "40px",
|
|
217
|
+
"btnSm": "32px",
|
|
218
|
+
"btnSearch": "38px",
|
|
219
|
+
"inputDefault": "39px",
|
|
220
|
+
"tapTarget": "44px"
|
|
221
|
+
},
|
|
222
|
+
"zIndex": {
|
|
223
|
+
"sidebar": "1000",
|
|
224
|
+
"dropdown": "1001",
|
|
225
|
+
"datepicker": "3000",
|
|
226
|
+
"stickyTopbar": "4000",
|
|
227
|
+
"modalBackdrop": "10050",
|
|
228
|
+
"modalDialog": "10051",
|
|
229
|
+
"preloader": "99999",
|
|
230
|
+
"topmostOverlay": "1000001"
|
|
231
|
+
},
|
|
232
|
+
"motion": {
|
|
233
|
+
"fast": "0.1s",
|
|
234
|
+
"default": "0.2s ease-in-out",
|
|
235
|
+
"slow": "0.3s",
|
|
236
|
+
"bouncy": "0.4s cubic-bezier(0.88, -0.99, 0, 1.81)"
|
|
237
|
+
}
|
|
238
|
+
} as const;
|
|
239
|
+
|
|
240
|
+
export type Tokens = typeof tokens;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# integration-smoke.sh — sanity checks for design-system as a consumed submodule/package.
|
|
3
|
+
#
|
|
4
|
+
# Runs:
|
|
5
|
+
# 1. `npm run build` is byte-stable (no drift in pre-built/ after rebuild)
|
|
6
|
+
# 2. `npm run validate` passes
|
|
7
|
+
# 3. Critical hf-prefixed tokens exist in pre-built/tailwind.css
|
|
8
|
+
# 4. Critical .hf-* primitives exist in pre-built/components.css
|
|
9
|
+
# 5. Every path in package.json `exports` resolves to an existing file
|
|
10
|
+
#
|
|
11
|
+
# Exits non-zero on any failure. Suitable for CI in this repo AND for running
|
|
12
|
+
# from a consumer project (e.g. `cd design-system && ./scripts/integration-smoke.sh`)
|
|
13
|
+
# right after `git submodule update --remote` to confirm the bumped pin is healthy.
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
cd "$(dirname "$0")/.."
|
|
18
|
+
|
|
19
|
+
fail() { printf '✗ %s\n' "$*" >&2; exit 1; }
|
|
20
|
+
ok() { printf '✓ %s\n' "$*"; }
|
|
21
|
+
|
|
22
|
+
# --- 1. Build is reproducible ----------------------------------------------
|
|
23
|
+
echo "→ rebuild + drift check"
|
|
24
|
+
npm run --silent build >/dev/null
|
|
25
|
+
if ! git diff --quiet -- pre-built/; then
|
|
26
|
+
git --no-pager diff --stat -- pre-built/
|
|
27
|
+
fail "pre-built/ drifts after rebuild — sources and outputs are out of sync"
|
|
28
|
+
fi
|
|
29
|
+
ok "pre-built/ is byte-stable"
|
|
30
|
+
|
|
31
|
+
# --- 2. Validator passes ---------------------------------------------------
|
|
32
|
+
echo "→ validate-tokens"
|
|
33
|
+
npm run --silent validate >/dev/null
|
|
34
|
+
ok "validate-tokens: all checks passed"
|
|
35
|
+
|
|
36
|
+
# --- 3. Tailwind v4 @theme has the canonical hf-prefixed tokens ------------
|
|
37
|
+
echo "→ tailwind.css canonical tokens"
|
|
38
|
+
required_tw=(
|
|
39
|
+
"--color-hf-accent"
|
|
40
|
+
"--color-hf-accent-hover"
|
|
41
|
+
"--color-hf-fg"
|
|
42
|
+
"--color-hf-border"
|
|
43
|
+
"--text-hf-base"
|
|
44
|
+
"--radius-hf-sm"
|
|
45
|
+
"--spacing-hf-7"
|
|
46
|
+
"--font-hf-sans"
|
|
47
|
+
"--shadow-hf-modal"
|
|
48
|
+
)
|
|
49
|
+
for name in "${required_tw[@]}"; do
|
|
50
|
+
grep -qF -- "$name" pre-built/tailwind.css \
|
|
51
|
+
|| fail "missing token in pre-built/tailwind.css: $name (Phase 1A regression?)"
|
|
52
|
+
done
|
|
53
|
+
ok "tailwind.css carries all canonical hf-prefixed tokens"
|
|
54
|
+
|
|
55
|
+
# --- 4. components.css has the headline .hf-* primitives -------------------
|
|
56
|
+
echo "→ components.css primitives"
|
|
57
|
+
required_hf=(
|
|
58
|
+
".hf-modal"
|
|
59
|
+
".hf-pill"
|
|
60
|
+
".hf-tab"
|
|
61
|
+
".hf-pagination"
|
|
62
|
+
".hf-alert"
|
|
63
|
+
".hf-check"
|
|
64
|
+
".hf-radio"
|
|
65
|
+
".hf-dropdown-menu"
|
|
66
|
+
)
|
|
67
|
+
for cls in "${required_hf[@]}"; do
|
|
68
|
+
grep -qF -- "$cls" pre-built/components.css \
|
|
69
|
+
|| fail "missing primitive in pre-built/components.css: $cls"
|
|
70
|
+
done
|
|
71
|
+
ok "components.css contains all headline .hf-* primitives"
|
|
72
|
+
|
|
73
|
+
# --- 5. Every exports path resolves ----------------------------------------
|
|
74
|
+
echo "→ package.json exports resolution"
|
|
75
|
+
node --input-type=module -e '
|
|
76
|
+
import("node:fs").then(({readFileSync, existsSync}) => {
|
|
77
|
+
const pkg = JSON.parse(readFileSync("package.json", "utf8"));
|
|
78
|
+
const flatten = (v) => typeof v === "string"
|
|
79
|
+
? [v]
|
|
80
|
+
: Object.values(v).flatMap(flatten);
|
|
81
|
+
const targets = Object.values(pkg.exports || {}).flatMap(flatten);
|
|
82
|
+
const missing = targets.filter(p => !existsSync(p.replace(/^\.\//, "")));
|
|
83
|
+
if (missing.length) {
|
|
84
|
+
console.error("missing exports targets:\n - " + missing.join("\n - "));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
' || fail "package.json exports references files that do not exist"
|
|
89
|
+
ok "all package.json exports resolve to existing files"
|
|
90
|
+
|
|
91
|
+
printf '\n✓ integration smoke OK — design-system is ready to consume.\n'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Pre-commit hook — runs validate-tokens.cjs to catch design-system drift
|
|
3
|
+
# before commit. Drop into .husky/pre-commit (with husky) or .git/hooks/pre-commit.
|
|
4
|
+
#
|
|
5
|
+
# Phase 3C (RFC-0001 §4.6) — drift detection enforcement.
|
|
6
|
+
#
|
|
7
|
+
# Setup:
|
|
8
|
+
#
|
|
9
|
+
# With husky (recommended):
|
|
10
|
+
# pnpm add -D husky
|
|
11
|
+
# pnpm husky init
|
|
12
|
+
# cp docs/portable-design/scripts/pre-commit.sh .husky/pre-commit
|
|
13
|
+
# chmod +x .husky/pre-commit
|
|
14
|
+
#
|
|
15
|
+
# Without husky (raw git hook):
|
|
16
|
+
# cp docs/portable-design/scripts/pre-commit.sh .git/hooks/pre-commit
|
|
17
|
+
# chmod +x .git/hooks/pre-commit
|
|
18
|
+
#
|
|
19
|
+
# The hook is silent on success and prints a clear error list on failure.
|
|
20
|
+
|
|
21
|
+
set -e
|
|
22
|
+
|
|
23
|
+
# Resolve the bundle path. Adjust if your bundle lives elsewhere.
|
|
24
|
+
BUNDLE_DIR="docs/portable-design"
|
|
25
|
+
|
|
26
|
+
if [ ! -d "$BUNDLE_DIR" ]; then
|
|
27
|
+
# If bundle moved, try common alternatives
|
|
28
|
+
for alt in "design-system" "packages/design-tokens" "."; do
|
|
29
|
+
if [ -f "$alt/scripts/validate-tokens.cjs" ]; then
|
|
30
|
+
BUNDLE_DIR="$alt"
|
|
31
|
+
break
|
|
32
|
+
fi
|
|
33
|
+
done
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ ! -f "$BUNDLE_DIR/scripts/validate-tokens.cjs" ]; then
|
|
37
|
+
echo "⚠ pre-commit: validate-tokens.cjs not found at $BUNDLE_DIR/scripts/"
|
|
38
|
+
echo " Skipping design-system drift check. Update BUNDLE_DIR in this hook."
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Only run if any token-related file is staged
|
|
43
|
+
STAGED=$(git diff --cached --name-only)
|
|
44
|
+
if echo "$STAGED" | grep -qE "$BUNDLE_DIR/(tokens\.figma\.json|status-map\.json|pre-built/.*\.(css|js|ts|cjs|scss)|.*\.md|components\.html|generate-tokens\.cjs)"; then
|
|
45
|
+
echo "→ Running design-system validator (changes detected in bundle)…"
|
|
46
|
+
cd "$BUNDLE_DIR"
|
|
47
|
+
if ! node scripts/validate-tokens.cjs; then
|
|
48
|
+
echo ""
|
|
49
|
+
echo "✗ pre-commit: design-system drift detected. Fix the issues above and re-commit."
|
|
50
|
+
echo " To bypass (NOT recommended), use: git commit --no-verify"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
exit 0
|