@empoweredvote/ev-ui 0.9.6 → 0.9.8
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 +111 -111
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tailwind-preset.js +81 -81
- package/src/tokens.js +415 -415
package/src/tokens.js
CHANGED
|
@@ -1,415 +1,415 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Empowered Vote Design Tokens
|
|
3
|
-
* Single source of truth for the EV design system.
|
|
4
|
-
* Synced to Penpot via /sync-design-tokens
|
|
5
|
-
*
|
|
6
|
-
* WCAG AA compliance notes:
|
|
7
|
-
* Brand colors have limited contrast on white backgrounds.
|
|
8
|
-
* Use the `accessibleText` map below for body-text alternatives
|
|
9
|
-
* that pass AA (4.5:1) while staying on-brand.
|
|
10
|
-
*
|
|
11
|
-
* Brand color | On white | AA-safe text alternative
|
|
12
|
-
* ───────────────── | ──────── | ────────────────────────
|
|
13
|
-
* Coral #FF5740 | 3.14:1 | coral-700 #E61B00 (4.64:1)
|
|
14
|
-
* Muted Blue #00657C | 6.66:1 | (already AA — use directly)
|
|
15
|
-
* Light Blue #59B0C4 | 2.49:1 | skyblue-700 #327E8F (4.65:1)
|
|
16
|
-
* Yellow #FED12E | 1.46:1 | yellow-900 #7B640E (5.72:1)
|
|
17
|
-
*
|
|
18
|
-
* Coral is AA for large text only (>=18px bold or >=24px).
|
|
19
|
-
* Yellow and Light Blue should never be used as text on white.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
// ──────────────────────────────────────────────
|
|
23
|
-
// Color Scales (050–950 per hue)
|
|
24
|
-
// ──────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
export const colorScales = {
|
|
27
|
-
coral: {
|
|
28
|
-
'050': '#FAF6F5', '100': '#F6E6E4', '200': '#F2C6C0', '300': '#F2988C',
|
|
29
|
-
'400': '#F66855', '500': '#FF5740', '600': '#FF2B0F', '700': '#E61B00',
|
|
30
|
-
'800': '#B31D09', '900': '#8E1F10', '950': '#6C1E13',
|
|
31
|
-
},
|
|
32
|
-
teal: {
|
|
33
|
-
// Smoothed scale — original 400→500 had a ~45 lightness jump.
|
|
34
|
-
// 400 now bridges the light wash into the deep brand muted-blue.
|
|
35
|
-
'050': '#F5F9FA', '100': '#E4F3F6', '200': '#C0E8F2', '300': '#7DD4E8',
|
|
36
|
-
'400': '#3AABB8', '500': '#00657C', '600': '#005366', '700': '#003E4D',
|
|
37
|
-
'800': '#03303A', '900': '#05262E', '950': '#051A1E',
|
|
38
|
-
},
|
|
39
|
-
skyblue: {
|
|
40
|
-
'050': '#F6F8F8', '100': '#E9F0F1', '200': '#CDE0E5', '300': '#A7CFD8',
|
|
41
|
-
'400': '#7FBECC', '500': '#59B0C4', '600': '#3A9BB0', '700': '#327E8F',
|
|
42
|
-
'800': '#2B616E', '900': '#264C55', '950': '#1E383D',
|
|
43
|
-
},
|
|
44
|
-
yellow: {
|
|
45
|
-
'050': '#FAF9F5', '100': '#F6F2E4', '200': '#F1E7C0', '300': '#F2DC8D',
|
|
46
|
-
'400': '#F5D356', '500': '#FED12E', '600': '#FAC400', '700': '#D0A301',
|
|
47
|
-
'800': '#9F7F09', '900': '#7B640E', '950': '#5B4B10',
|
|
48
|
-
},
|
|
49
|
-
gray: {
|
|
50
|
-
'050': '#F7F7F8', '100': '#EBEDEF', '200': '#D3D7DE', '300': '#B3BBCC',
|
|
51
|
-
'400': '#8F9EBC', '500': '#6B7280', '600': '#535964', '700': '#41454E',
|
|
52
|
-
'800': '#2F3237', '900': '#212326', '950': '#131416',
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// ──────────────────────────────────────────────
|
|
57
|
-
// Tier Colors (teal-scale shade variation)
|
|
58
|
-
// ──────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
export const tierColors = {
|
|
61
|
-
federal: {
|
|
62
|
-
bg: '#FFFFFF', // white — lightest tier
|
|
63
|
-
accent: colorScales.teal['700'], // #003E4D
|
|
64
|
-
text: colorScales.teal['700'], // #003E4D — 7.5:1 on white, AA
|
|
65
|
-
},
|
|
66
|
-
state: {
|
|
67
|
-
bg: '#F7FBFC', // gentle teal wash — midpoint between white and 050
|
|
68
|
-
accent: colorScales.teal['500'], // #00657C
|
|
69
|
-
text: colorScales.teal['500'], // #00657C — 6.66:1 on white, AA
|
|
70
|
-
},
|
|
71
|
-
local: {
|
|
72
|
-
bg: '#EDF6F8', // #EDF6F8 — between 050 and 100, darkest tier
|
|
73
|
-
accent: colorScales.teal['200'], // #C0E8F2 — decorative only
|
|
74
|
-
text: colorScales.teal['600'], // #005366 — 8.1:1 on white, AA
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// ──────────────────────────────────────────────
|
|
79
|
-
// Brand Colors (flat references for convenience)
|
|
80
|
-
// Canonical values — DO NOT change without updating all apps.
|
|
81
|
-
// ──────────────────────────────────────────────
|
|
82
|
-
|
|
83
|
-
export const colors = {
|
|
84
|
-
// Primary brand (locked)
|
|
85
|
-
evCoral: '#FF5740', // 3.14:1 on white — large text / UI only
|
|
86
|
-
evMutedBlue: '#00657C', // 6.66:1 on white — AA body text safe
|
|
87
|
-
evLightBlue: '#59B0C4', // 2.49:1 on white — decorative / dark bg only
|
|
88
|
-
evYellow: '#FED12E', // 1.46:1 on white — accent / dark bg only
|
|
89
|
-
evYellowLight:'#FEF3C7',
|
|
90
|
-
evYellowDark: '#D0A301',
|
|
91
|
-
black: '#1C1C1C',
|
|
92
|
-
white: '#FFFFFF',
|
|
93
|
-
|
|
94
|
-
// Legacy aliases (deprecated — use evMutedBlue / evLightBlue instead)
|
|
95
|
-
evTeal: '#00657C',
|
|
96
|
-
evTealDark: '#003E4D',
|
|
97
|
-
evTealLight: '#59B0C4',
|
|
98
|
-
|
|
99
|
-
// Backgrounds
|
|
100
|
-
bgLight: '#F0F8FA',
|
|
101
|
-
bgWhite: '#FFFFFF',
|
|
102
|
-
|
|
103
|
-
// Text
|
|
104
|
-
textPrimary: '#00657C', // Muted Blue — 6.66:1 on white ✓ AA
|
|
105
|
-
textSecondary: '#4A5568', // ~6.0:1 on white ✓ AA
|
|
106
|
-
textMuted: '#718096', // ~4.6:1 on white ✓ AA
|
|
107
|
-
textWhite: '#FFFFFF',
|
|
108
|
-
|
|
109
|
-
// Borders
|
|
110
|
-
borderLight: '#E2EBEF',
|
|
111
|
-
borderMedium: '#C9CFD1',
|
|
112
|
-
|
|
113
|
-
// State
|
|
114
|
-
error: '#EF4444',
|
|
115
|
-
errorLight: '#FEF2F2',
|
|
116
|
-
success: '#22C55E',
|
|
117
|
-
successLight: '#F0FDF4',
|
|
118
|
-
warning: '#F59E0B',
|
|
119
|
-
warningLight: '#FFFBEB',
|
|
120
|
-
info: '#3A9BB0',
|
|
121
|
-
infoLight: '#F5F9FA',
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// ──────────────────────────────────────────────
|
|
125
|
-
// AA-Safe Text Colors (per brand hue)
|
|
126
|
-
// Use these when a brand color must appear as readable text.
|
|
127
|
-
// Each passes WCAG AA (4.5:1+) on white and bgLight.
|
|
128
|
-
// ──────────────────────────────────────────────
|
|
129
|
-
|
|
130
|
-
export const accessibleText = {
|
|
131
|
-
coral: '#E61B00', // coral-700, 4.64:1 on white
|
|
132
|
-
teal: '#00657C', // teal-500 (brand muted blue), 6.66:1
|
|
133
|
-
skyblue: '#327E8F', // skyblue-700, 4.65:1 on white
|
|
134
|
-
yellow: '#7B640E', // yellow-900, 5.72:1 on white
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// ──────────────────────────────────────────────
|
|
138
|
-
// Pillar Themes
|
|
139
|
-
// ──────────────────────────────────────────────
|
|
140
|
-
|
|
141
|
-
export const pillars = {
|
|
142
|
-
inform: {
|
|
143
|
-
name: 'Inform', accent: 'yellow',
|
|
144
|
-
color: '#FED12E', dark: '#D0A301', light: '#FAF9F5',
|
|
145
|
-
textColor: '#7B640E', // AA-safe text — yellow-900
|
|
146
|
-
darkMode: { color: '#FED12E', dark: '#FEE88A', textOnAccent: '#1C1C1C' },
|
|
147
|
-
},
|
|
148
|
-
empower: {
|
|
149
|
-
name: 'Empower', accent: 'coral',
|
|
150
|
-
color: '#FF5740', dark: '#E61B00', light: '#FAF6F5',
|
|
151
|
-
textColor: '#E61B00', // AA-safe text — coral-700
|
|
152
|
-
darkMode: { color: '#FF5740', dark: '#F66855', textOnAccent: '#FFFFFF' },
|
|
153
|
-
},
|
|
154
|
-
connect: {
|
|
155
|
-
name: 'Connect', accent: 'teal',
|
|
156
|
-
color: '#00657C', dark: '#003E4D', light: '#F5F9FA',
|
|
157
|
-
textColor: '#00657C', // Already AA — muted blue
|
|
158
|
-
darkMode: { color: '#3A9BB0', dark: '#59B0C4', textOnAccent: '#FFFFFF' },
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// ──────────────────────────────────────────────
|
|
163
|
-
// Semantic Tokens (Light / Dark)
|
|
164
|
-
// All text-on-background pairings verified AA (4.5:1+).
|
|
165
|
-
// ──────────────────────────────────────────────
|
|
166
|
-
|
|
167
|
-
export const semanticTokens = {
|
|
168
|
-
light: {
|
|
169
|
-
layerBase: { background: '#F7F7F8', text: '#535964', icon: '#535964', border: '#D3D7DE' }, // 6.58:1
|
|
170
|
-
layerOne: { background: '#EBEDEF', text: '#41454E', icon: '#41454E', border: '#D3D7DE' }, // 7.23:1
|
|
171
|
-
layerTwo: { background: '#D3D7DE', text: '#2F3237', icon: '#2F3237', border: '#B3BBCC' }, // 7.60:1
|
|
172
|
-
heading: { text: '#2F3237' }, // 12.02:1 on gray-050
|
|
173
|
-
divider: '#D3D7DE',
|
|
174
|
-
link: { default: '#00657C', hovered: '#003E4D', focused: '#003E4D', pressed: '#003E4D' },
|
|
175
|
-
input: { background: '#F7F7F8', text: '#41454E', border: '#41454E', icon: '#6B7280' }, // text bumped from gray-500 to gray-700 for AA
|
|
176
|
-
buttonPrimary: {
|
|
177
|
-
background: { default: '#005366', hovered: '#003E4D', pressed: '#03303A', focused: '#005366', disabled: '#D3D7DE' },
|
|
178
|
-
text: { default: '#FFFFFF', disabled: '#8F9EBC' },
|
|
179
|
-
},
|
|
180
|
-
buttonSecondary: {
|
|
181
|
-
background: { default: '#F7F7F8', hovered: '#EBEDEF', pressed: '#D3D7DE', focused: '#EBEDEF', disabled: '#F7F7F8' },
|
|
182
|
-
text: { default: '#003E4D', disabled: '#8F9EBC' },
|
|
183
|
-
border: { default: '#003E4D', disabled: '#D3D7DE' },
|
|
184
|
-
},
|
|
185
|
-
// Feedback states
|
|
186
|
-
badge: { background: '#EBEDEF', text: '#41454E', border: '#D3D7DE' },
|
|
187
|
-
tooltip: { background: '#2F3237', text: '#EBEDEF' },
|
|
188
|
-
overlay: 'rgba(19, 20, 22, 0.5)',
|
|
189
|
-
skeleton: { from: '#EBEDEF', to: '#D3D7DE' },
|
|
190
|
-
},
|
|
191
|
-
dark: {
|
|
192
|
-
layerBase: { background: '#131416', text: '#B3BBCC', icon: '#B3BBCC', border: '#41454E' }, // 9.56:1 ✓ AAA
|
|
193
|
-
layerOne: { background: '#2F3237', text: '#D3D7DE', icon: '#D3D7DE', border: '#41454E' }, // 8.91:1 ✓ AAA
|
|
194
|
-
layerTwo: { background: '#41454E', text: '#EBEDEF', icon: '#EBEDEF', border: '#535964' }, // 8.18:1 ✓ AAA
|
|
195
|
-
heading: { text: '#EBEDEF' }, // 15.70:1 on layerBase ✓ AAA
|
|
196
|
-
divider: '#41454E',
|
|
197
|
-
link: { default: '#59B0C4', hovered: '#7FBECC', focused: '#7FBECC', pressed: '#3A9BB0' }, // 7.40:1 on layerBase ✓ AAA
|
|
198
|
-
input: { background: '#1E2024', text: '#D3D7DE', border: '#6B7280', icon: '#B3BBCC' }, // border bumped to gray-500 for 3.37:1 UI ✓
|
|
199
|
-
buttonPrimary: {
|
|
200
|
-
// Darkened from skyblue to teal for white-text AA compliance
|
|
201
|
-
background: { default: '#005366', hovered: '#327E8F', pressed: '#003E4D', focused: '#005366', disabled: '#2F3237' },
|
|
202
|
-
text: { default: '#FFFFFF', disabled: '#535964' }, // 8.64:1 / 4.65:1 / 11.69:1 ✓ AA+
|
|
203
|
-
},
|
|
204
|
-
buttonSecondary: {
|
|
205
|
-
background: { default: '#131416', hovered: '#2F3237', pressed: '#41454E', focused: '#2F3237', disabled: '#131416' },
|
|
206
|
-
text: { default: '#59B0C4', disabled: '#535964' }, // 7.40:1 ✓ AAA
|
|
207
|
-
border: { default: '#59B0C4', disabled: '#41454E' },
|
|
208
|
-
},
|
|
209
|
-
// Feedback states
|
|
210
|
-
badge: { background: '#41454E', text: '#EBEDEF', border: '#535964' },
|
|
211
|
-
tooltip: { background: '#EBEDEF', text: '#2F3237' },
|
|
212
|
-
overlay: 'rgba(19, 20, 22, 0.75)',
|
|
213
|
-
skeleton: { from: '#2F3237', to: '#41454E' },
|
|
214
|
-
},
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
// ──────────────────────────────────────────────
|
|
218
|
-
// Data Visualization Palette
|
|
219
|
-
// ──────────────────────────────────────────────
|
|
220
|
-
|
|
221
|
-
// 10 hues derived from the EV brand palette.
|
|
222
|
-
// Core 4 (teal, sky blue, coral, yellow) + 6 harmonious neighbors.
|
|
223
|
-
// Each has 5 shades: [100-light, 300, 400, base-500, 700-dark]
|
|
224
|
-
export const dataVizPalette = [
|
|
225
|
-
{ name: 'Teal', base: '#00657C', shades: ['#C0E8F2', '#55D9F6', '#3AABB8', '#00657C', '#003E4D'] },
|
|
226
|
-
{ name: 'Sky Blue', base: '#59B0C4', shades: ['#CDE0E5', '#A7CFD8', '#7FBECC', '#59B0C4', '#327E8F'] },
|
|
227
|
-
{ name: 'Ocean', base: '#2563A0', shades: ['#CDDCED', '#7BADD4', '#4D8FC2', '#2563A0', '#193F68'] },
|
|
228
|
-
{ name: 'Coral', base: '#FF5740', shades: ['#F6E6E4', '#F2988C', '#F66855', '#FF5740', '#B31D09'] },
|
|
229
|
-
{ name: 'Terracotta', base: '#C2674A', shades: ['#F0DCD4', '#D9A48E', '#CF8568', '#C2674A', '#7A3D2C'] },
|
|
230
|
-
{ name: 'Yellow', base: '#FED12E', shades: ['#F6F2E4', '#F2DC8D', '#F5D356', '#FED12E', '#9F7F09'] },
|
|
231
|
-
{ name: 'Honey', base: '#D4940B', shades: ['#F5EACE', '#E8C563', '#DCA930', '#D4940B', '#805A06'] },
|
|
232
|
-
{ name: 'Sage', base: '#5A9A6E', shades: ['#D4E8DA', '#9ACBAA', '#74B589', '#5A9A6E', '#376043'] },
|
|
233
|
-
{ name: 'Dusk', base: '#7C6B9E', shades: ['#E4DFF0', '#B5A8CF', '#9788B8', '#7C6B9E', '#4D4263'] },
|
|
234
|
-
{ name: 'Stone', base: '#6B7280', shades: ['#EBEDEF', '#B3BBCC', '#8F9EBC', '#6B7280', '#41454E'] },
|
|
235
|
-
];
|
|
236
|
-
|
|
237
|
-
// ──────────────────────────────────────────────
|
|
238
|
-
// Typography
|
|
239
|
-
// ──────────────────────────────────────────────
|
|
240
|
-
|
|
241
|
-
export const fonts = {
|
|
242
|
-
primary: "'Manrope', sans-serif",
|
|
243
|
-
fallback: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
export const fontWeights = {
|
|
247
|
-
regular: 400,
|
|
248
|
-
medium: 500,
|
|
249
|
-
semibold: 600,
|
|
250
|
-
bold: 700,
|
|
251
|
-
extrabold: 800,
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
export const fontSizes = {
|
|
255
|
-
xs: '12px',
|
|
256
|
-
sm: '14px',
|
|
257
|
-
base: '16px',
|
|
258
|
-
lg: '18px',
|
|
259
|
-
xl: '20px',
|
|
260
|
-
'2xl': '24px',
|
|
261
|
-
'3xl': '30px',
|
|
262
|
-
'4xl': '36px',
|
|
263
|
-
'5xl': '48px',
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
export const lineHeights = {
|
|
267
|
-
tight: 1.25,
|
|
268
|
-
normal: 1.5,
|
|
269
|
-
relaxed: 1.75,
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
export const letterSpacing = {
|
|
273
|
-
tight: '-0.02em',
|
|
274
|
-
normal: '0',
|
|
275
|
-
wide: '0.05em',
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
// Composite text styles — combine size, weight, line-height, and letter-spacing
|
|
279
|
-
// into ready-to-spread objects for inline styles: style={{ ...textStyles.displayTitle }}
|
|
280
|
-
export const textStyles = {
|
|
281
|
-
displayTitle: { fontSize: '48px', fontWeight: 800, lineHeight: 1.1, letterSpacing: '-0.03em' },
|
|
282
|
-
displaySub: { fontSize: '36px', fontWeight: 700, lineHeight: 1.15, letterSpacing: '-0.02em' },
|
|
283
|
-
h1: { fontSize: '30px', fontWeight: 700, lineHeight: 1.25, letterSpacing: '-0.02em' },
|
|
284
|
-
h2: { fontSize: '24px', fontWeight: 700, lineHeight: 1.3, letterSpacing: '-0.01em' },
|
|
285
|
-
h3: { fontSize: '20px', fontWeight: 600, lineHeight: 1.35, letterSpacing: '0' },
|
|
286
|
-
h4: { fontSize: '18px', fontWeight: 600, lineHeight: 1.4, letterSpacing: '0' },
|
|
287
|
-
bodyLg: { fontSize: '18px', fontWeight: 400, lineHeight: 1.6, letterSpacing: '0' },
|
|
288
|
-
body: { fontSize: '16px', fontWeight: 400, lineHeight: 1.5, letterSpacing: '0' },
|
|
289
|
-
bodySm: { fontSize: '14px', fontWeight: 400, lineHeight: 1.5, letterSpacing: '0' },
|
|
290
|
-
label: { fontSize: '14px', fontWeight: 500, lineHeight: 1.4, letterSpacing: '0.01em' },
|
|
291
|
-
labelSm: { fontSize: '12px', fontWeight: 500, lineHeight: 1.4, letterSpacing: '0.02em' },
|
|
292
|
-
caption: { fontSize: '12px', fontWeight: 400, lineHeight: 1.4, letterSpacing: '0.01em' },
|
|
293
|
-
overline: { fontSize: '11px', fontWeight: 700, lineHeight: 1.4, letterSpacing: '0.08em', textTransform: 'uppercase' },
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
// ──────────────────────────────────────────────
|
|
297
|
-
// Spacing (4px base unit)
|
|
298
|
-
// ──────────────────────────────────────────────
|
|
299
|
-
|
|
300
|
-
export const spacing = {
|
|
301
|
-
0: '0',
|
|
302
|
-
'050': '2px',
|
|
303
|
-
1: '4px',
|
|
304
|
-
'150': '6px',
|
|
305
|
-
2: '8px',
|
|
306
|
-
3: '12px',
|
|
307
|
-
4: '16px',
|
|
308
|
-
5: '20px',
|
|
309
|
-
6: '24px',
|
|
310
|
-
8: '32px',
|
|
311
|
-
10: '40px',
|
|
312
|
-
12: '48px',
|
|
313
|
-
16: '64px',
|
|
314
|
-
20: '80px',
|
|
315
|
-
24: '96px',
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// ──────────────────────────────────────────────
|
|
319
|
-
// Border Radius
|
|
320
|
-
// ──────────────────────────────────────────────
|
|
321
|
-
|
|
322
|
-
export const borderRadius = {
|
|
323
|
-
none: '0',
|
|
324
|
-
sm: '4px',
|
|
325
|
-
md: '8px',
|
|
326
|
-
lg: '10px',
|
|
327
|
-
xl: '12px',
|
|
328
|
-
'2xl': '16px',
|
|
329
|
-
full: '9999px',
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
// ──────────────────────────────────────────────
|
|
333
|
-
// Shadows & Elevation
|
|
334
|
-
// ──────────────────────────────────────────────
|
|
335
|
-
|
|
336
|
-
export const shadows = {
|
|
337
|
-
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
338
|
-
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
|
|
339
|
-
lg: '0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 10px -4px rgba(0, 0, 0, 0.05)',
|
|
340
|
-
xl: '0 20px 40px -8px rgba(0, 0, 0, 0.12), 0 8px 16px -6px rgba(0, 0, 0, 0.06)',
|
|
341
|
-
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
|
|
342
|
-
glowCoral: '0 0 0 3px rgba(255, 87, 64, 0.25)',
|
|
343
|
-
glowTeal: '0 0 0 3px rgba(0, 101, 124, 0.2)',
|
|
344
|
-
cardHover: '0 12px 32px -4px rgba(0, 0, 0, 0.12), 0 4px 8px -2px rgba(0, 0, 0, 0.04)',
|
|
345
|
-
none: 'none',
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// ──────────────────────────────────────────────
|
|
349
|
-
// Motion
|
|
350
|
-
// ──────────────────────────────────────────────
|
|
351
|
-
|
|
352
|
-
export const duration = {
|
|
353
|
-
instant: '50ms',
|
|
354
|
-
fast: '120ms', // Micro-interactions: toggles, checkboxes
|
|
355
|
-
normal: '200ms', // Buttons, inputs, small transitions
|
|
356
|
-
slow: '350ms', // Panels, cards, modals
|
|
357
|
-
slower: '500ms', // Page transitions, complex orchestration
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
export const easing = {
|
|
361
|
-
default: 'cubic-bezier(0.2, 0, 0, 1)', // General-purpose (Material 3 standard)
|
|
362
|
-
enter: 'cubic-bezier(0, 0, 0.2, 1)', // Elements appearing (decelerate)
|
|
363
|
-
exit: 'cubic-bezier(0.4, 0, 1, 1)', // Elements leaving (accelerate)
|
|
364
|
-
spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)', // Playful overshoot — buttons, badges
|
|
365
|
-
linear: 'linear',
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
// ──────────────────────────────────────────────
|
|
369
|
-
// Focus Ring
|
|
370
|
-
// ──────────────────────────────────────────────
|
|
371
|
-
|
|
372
|
-
export const focus = {
|
|
373
|
-
ring: '0 0 0 2px #FFFFFF, 0 0 0 4px #00657C', // White gap + brand muted blue (6.66:1 on white)
|
|
374
|
-
ringDark: '0 0 0 2px #131416, 0 0 0 4px #59B0C4', // Dark gap + light blue (6.84:1 on dark)
|
|
375
|
-
ringCoral: '0 0 0 2px #FFFFFF, 0 0 0 4px #FF5740', // Coral variant for pillar contexts
|
|
376
|
-
offset: '2px',
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
// ──────────────────────────────────────────────
|
|
380
|
-
// Z-Index Scale
|
|
381
|
-
// ──────────────────────────────────────────────
|
|
382
|
-
|
|
383
|
-
export const zIndex = {
|
|
384
|
-
hide: -1,
|
|
385
|
-
base: 0,
|
|
386
|
-
dropdown: 10,
|
|
387
|
-
sticky: 20,
|
|
388
|
-
header: 30,
|
|
389
|
-
overlay: 40,
|
|
390
|
-
modal: 50,
|
|
391
|
-
toast: 60,
|
|
392
|
-
tooltip: 70,
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
// ──────────────────────────────────────────────
|
|
396
|
-
// Opacity
|
|
397
|
-
// ──────────────────────────────────────────────
|
|
398
|
-
|
|
399
|
-
export const opacity = {
|
|
400
|
-
disabled: 0.4,
|
|
401
|
-
muted: 0.6,
|
|
402
|
-
subtle: 0.8,
|
|
403
|
-
full: 1,
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
// ──────────────────────────────────────────────
|
|
407
|
-
// Breakpoints
|
|
408
|
-
// ──────────────────────────────────────────────
|
|
409
|
-
|
|
410
|
-
export const breakpoints = {
|
|
411
|
-
sm: '640px',
|
|
412
|
-
md: '768px',
|
|
413
|
-
lg: '1024px',
|
|
414
|
-
xl: '1280px',
|
|
415
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Empowered Vote Design Tokens
|
|
3
|
+
* Single source of truth for the EV design system.
|
|
4
|
+
* Synced to Penpot via /sync-design-tokens
|
|
5
|
+
*
|
|
6
|
+
* WCAG AA compliance notes:
|
|
7
|
+
* Brand colors have limited contrast on white backgrounds.
|
|
8
|
+
* Use the `accessibleText` map below for body-text alternatives
|
|
9
|
+
* that pass AA (4.5:1) while staying on-brand.
|
|
10
|
+
*
|
|
11
|
+
* Brand color | On white | AA-safe text alternative
|
|
12
|
+
* ───────────────── | ──────── | ────────────────────────
|
|
13
|
+
* Coral #FF5740 | 3.14:1 | coral-700 #E61B00 (4.64:1)
|
|
14
|
+
* Muted Blue #00657C | 6.66:1 | (already AA — use directly)
|
|
15
|
+
* Light Blue #59B0C4 | 2.49:1 | skyblue-700 #327E8F (4.65:1)
|
|
16
|
+
* Yellow #FED12E | 1.46:1 | yellow-900 #7B640E (5.72:1)
|
|
17
|
+
*
|
|
18
|
+
* Coral is AA for large text only (>=18px bold or >=24px).
|
|
19
|
+
* Yellow and Light Blue should never be used as text on white.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// ──────────────────────────────────────────────
|
|
23
|
+
// Color Scales (050–950 per hue)
|
|
24
|
+
// ──────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
export const colorScales = {
|
|
27
|
+
coral: {
|
|
28
|
+
'050': '#FAF6F5', '100': '#F6E6E4', '200': '#F2C6C0', '300': '#F2988C',
|
|
29
|
+
'400': '#F66855', '500': '#FF5740', '600': '#FF2B0F', '700': '#E61B00',
|
|
30
|
+
'800': '#B31D09', '900': '#8E1F10', '950': '#6C1E13',
|
|
31
|
+
},
|
|
32
|
+
teal: {
|
|
33
|
+
// Smoothed scale — original 400→500 had a ~45 lightness jump.
|
|
34
|
+
// 400 now bridges the light wash into the deep brand muted-blue.
|
|
35
|
+
'050': '#F5F9FA', '100': '#E4F3F6', '200': '#C0E8F2', '300': '#7DD4E8',
|
|
36
|
+
'400': '#3AABB8', '500': '#00657C', '600': '#005366', '700': '#003E4D',
|
|
37
|
+
'800': '#03303A', '900': '#05262E', '950': '#051A1E',
|
|
38
|
+
},
|
|
39
|
+
skyblue: {
|
|
40
|
+
'050': '#F6F8F8', '100': '#E9F0F1', '200': '#CDE0E5', '300': '#A7CFD8',
|
|
41
|
+
'400': '#7FBECC', '500': '#59B0C4', '600': '#3A9BB0', '700': '#327E8F',
|
|
42
|
+
'800': '#2B616E', '900': '#264C55', '950': '#1E383D',
|
|
43
|
+
},
|
|
44
|
+
yellow: {
|
|
45
|
+
'050': '#FAF9F5', '100': '#F6F2E4', '200': '#F1E7C0', '300': '#F2DC8D',
|
|
46
|
+
'400': '#F5D356', '500': '#FED12E', '600': '#FAC400', '700': '#D0A301',
|
|
47
|
+
'800': '#9F7F09', '900': '#7B640E', '950': '#5B4B10',
|
|
48
|
+
},
|
|
49
|
+
gray: {
|
|
50
|
+
'050': '#F7F7F8', '100': '#EBEDEF', '200': '#D3D7DE', '300': '#B3BBCC',
|
|
51
|
+
'400': '#8F9EBC', '500': '#6B7280', '600': '#535964', '700': '#41454E',
|
|
52
|
+
'800': '#2F3237', '900': '#212326', '950': '#131416',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// ──────────────────────────────────────────────
|
|
57
|
+
// Tier Colors (teal-scale shade variation)
|
|
58
|
+
// ──────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export const tierColors = {
|
|
61
|
+
federal: {
|
|
62
|
+
bg: '#FFFFFF', // white — lightest tier
|
|
63
|
+
accent: colorScales.teal['700'], // #003E4D
|
|
64
|
+
text: colorScales.teal['700'], // #003E4D — 7.5:1 on white, AA
|
|
65
|
+
},
|
|
66
|
+
state: {
|
|
67
|
+
bg: '#F7FBFC', // gentle teal wash — midpoint between white and 050
|
|
68
|
+
accent: colorScales.teal['500'], // #00657C
|
|
69
|
+
text: colorScales.teal['500'], // #00657C — 6.66:1 on white, AA
|
|
70
|
+
},
|
|
71
|
+
local: {
|
|
72
|
+
bg: '#EDF6F8', // #EDF6F8 — between 050 and 100, darkest tier
|
|
73
|
+
accent: colorScales.teal['200'], // #C0E8F2 — decorative only
|
|
74
|
+
text: colorScales.teal['600'], // #005366 — 8.1:1 on white, AA
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// ──────────────────────────────────────────────
|
|
79
|
+
// Brand Colors (flat references for convenience)
|
|
80
|
+
// Canonical values — DO NOT change without updating all apps.
|
|
81
|
+
// ──────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
export const colors = {
|
|
84
|
+
// Primary brand (locked)
|
|
85
|
+
evCoral: '#FF5740', // 3.14:1 on white — large text / UI only
|
|
86
|
+
evMutedBlue: '#00657C', // 6.66:1 on white — AA body text safe
|
|
87
|
+
evLightBlue: '#59B0C4', // 2.49:1 on white — decorative / dark bg only
|
|
88
|
+
evYellow: '#FED12E', // 1.46:1 on white — accent / dark bg only
|
|
89
|
+
evYellowLight:'#FEF3C7',
|
|
90
|
+
evYellowDark: '#D0A301',
|
|
91
|
+
black: '#1C1C1C',
|
|
92
|
+
white: '#FFFFFF',
|
|
93
|
+
|
|
94
|
+
// Legacy aliases (deprecated — use evMutedBlue / evLightBlue instead)
|
|
95
|
+
evTeal: '#00657C',
|
|
96
|
+
evTealDark: '#003E4D',
|
|
97
|
+
evTealLight: '#59B0C4',
|
|
98
|
+
|
|
99
|
+
// Backgrounds
|
|
100
|
+
bgLight: '#F0F8FA',
|
|
101
|
+
bgWhite: '#FFFFFF',
|
|
102
|
+
|
|
103
|
+
// Text
|
|
104
|
+
textPrimary: '#00657C', // Muted Blue — 6.66:1 on white ✓ AA
|
|
105
|
+
textSecondary: '#4A5568', // ~6.0:1 on white ✓ AA
|
|
106
|
+
textMuted: '#718096', // ~4.6:1 on white ✓ AA
|
|
107
|
+
textWhite: '#FFFFFF',
|
|
108
|
+
|
|
109
|
+
// Borders
|
|
110
|
+
borderLight: '#E2EBEF',
|
|
111
|
+
borderMedium: '#C9CFD1',
|
|
112
|
+
|
|
113
|
+
// State
|
|
114
|
+
error: '#EF4444',
|
|
115
|
+
errorLight: '#FEF2F2',
|
|
116
|
+
success: '#22C55E',
|
|
117
|
+
successLight: '#F0FDF4',
|
|
118
|
+
warning: '#F59E0B',
|
|
119
|
+
warningLight: '#FFFBEB',
|
|
120
|
+
info: '#3A9BB0',
|
|
121
|
+
infoLight: '#F5F9FA',
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// ──────────────────────────────────────────────
|
|
125
|
+
// AA-Safe Text Colors (per brand hue)
|
|
126
|
+
// Use these when a brand color must appear as readable text.
|
|
127
|
+
// Each passes WCAG AA (4.5:1+) on white and bgLight.
|
|
128
|
+
// ──────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
export const accessibleText = {
|
|
131
|
+
coral: '#E61B00', // coral-700, 4.64:1 on white
|
|
132
|
+
teal: '#00657C', // teal-500 (brand muted blue), 6.66:1
|
|
133
|
+
skyblue: '#327E8F', // skyblue-700, 4.65:1 on white
|
|
134
|
+
yellow: '#7B640E', // yellow-900, 5.72:1 on white
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// ──────────────────────────────────────────────
|
|
138
|
+
// Pillar Themes
|
|
139
|
+
// ──────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
export const pillars = {
|
|
142
|
+
inform: {
|
|
143
|
+
name: 'Inform', accent: 'yellow',
|
|
144
|
+
color: '#FED12E', dark: '#D0A301', light: '#FAF9F5',
|
|
145
|
+
textColor: '#7B640E', // AA-safe text — yellow-900
|
|
146
|
+
darkMode: { color: '#FED12E', dark: '#FEE88A', textOnAccent: '#1C1C1C' },
|
|
147
|
+
},
|
|
148
|
+
empower: {
|
|
149
|
+
name: 'Empower', accent: 'coral',
|
|
150
|
+
color: '#FF5740', dark: '#E61B00', light: '#FAF6F5',
|
|
151
|
+
textColor: '#E61B00', // AA-safe text — coral-700
|
|
152
|
+
darkMode: { color: '#FF5740', dark: '#F66855', textOnAccent: '#FFFFFF' },
|
|
153
|
+
},
|
|
154
|
+
connect: {
|
|
155
|
+
name: 'Connect', accent: 'teal',
|
|
156
|
+
color: '#00657C', dark: '#003E4D', light: '#F5F9FA',
|
|
157
|
+
textColor: '#00657C', // Already AA — muted blue
|
|
158
|
+
darkMode: { color: '#3A9BB0', dark: '#59B0C4', textOnAccent: '#FFFFFF' },
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// ──────────────────────────────────────────────
|
|
163
|
+
// Semantic Tokens (Light / Dark)
|
|
164
|
+
// All text-on-background pairings verified AA (4.5:1+).
|
|
165
|
+
// ──────────────────────────────────────────────
|
|
166
|
+
|
|
167
|
+
export const semanticTokens = {
|
|
168
|
+
light: {
|
|
169
|
+
layerBase: { background: '#F7F7F8', text: '#535964', icon: '#535964', border: '#D3D7DE' }, // 6.58:1
|
|
170
|
+
layerOne: { background: '#EBEDEF', text: '#41454E', icon: '#41454E', border: '#D3D7DE' }, // 7.23:1
|
|
171
|
+
layerTwo: { background: '#D3D7DE', text: '#2F3237', icon: '#2F3237', border: '#B3BBCC' }, // 7.60:1
|
|
172
|
+
heading: { text: '#2F3237' }, // 12.02:1 on gray-050
|
|
173
|
+
divider: '#D3D7DE',
|
|
174
|
+
link: { default: '#00657C', hovered: '#003E4D', focused: '#003E4D', pressed: '#003E4D' },
|
|
175
|
+
input: { background: '#F7F7F8', text: '#41454E', border: '#41454E', icon: '#6B7280' }, // text bumped from gray-500 to gray-700 for AA
|
|
176
|
+
buttonPrimary: {
|
|
177
|
+
background: { default: '#005366', hovered: '#003E4D', pressed: '#03303A', focused: '#005366', disabled: '#D3D7DE' },
|
|
178
|
+
text: { default: '#FFFFFF', disabled: '#8F9EBC' },
|
|
179
|
+
},
|
|
180
|
+
buttonSecondary: {
|
|
181
|
+
background: { default: '#F7F7F8', hovered: '#EBEDEF', pressed: '#D3D7DE', focused: '#EBEDEF', disabled: '#F7F7F8' },
|
|
182
|
+
text: { default: '#003E4D', disabled: '#8F9EBC' },
|
|
183
|
+
border: { default: '#003E4D', disabled: '#D3D7DE' },
|
|
184
|
+
},
|
|
185
|
+
// Feedback states
|
|
186
|
+
badge: { background: '#EBEDEF', text: '#41454E', border: '#D3D7DE' },
|
|
187
|
+
tooltip: { background: '#2F3237', text: '#EBEDEF' },
|
|
188
|
+
overlay: 'rgba(19, 20, 22, 0.5)',
|
|
189
|
+
skeleton: { from: '#EBEDEF', to: '#D3D7DE' },
|
|
190
|
+
},
|
|
191
|
+
dark: {
|
|
192
|
+
layerBase: { background: '#131416', text: '#B3BBCC', icon: '#B3BBCC', border: '#41454E' }, // 9.56:1 ✓ AAA
|
|
193
|
+
layerOne: { background: '#2F3237', text: '#D3D7DE', icon: '#D3D7DE', border: '#41454E' }, // 8.91:1 ✓ AAA
|
|
194
|
+
layerTwo: { background: '#41454E', text: '#EBEDEF', icon: '#EBEDEF', border: '#535964' }, // 8.18:1 ✓ AAA
|
|
195
|
+
heading: { text: '#EBEDEF' }, // 15.70:1 on layerBase ✓ AAA
|
|
196
|
+
divider: '#41454E',
|
|
197
|
+
link: { default: '#59B0C4', hovered: '#7FBECC', focused: '#7FBECC', pressed: '#3A9BB0' }, // 7.40:1 on layerBase ✓ AAA
|
|
198
|
+
input: { background: '#1E2024', text: '#D3D7DE', border: '#6B7280', icon: '#B3BBCC' }, // border bumped to gray-500 for 3.37:1 UI ✓
|
|
199
|
+
buttonPrimary: {
|
|
200
|
+
// Darkened from skyblue to teal for white-text AA compliance
|
|
201
|
+
background: { default: '#005366', hovered: '#327E8F', pressed: '#003E4D', focused: '#005366', disabled: '#2F3237' },
|
|
202
|
+
text: { default: '#FFFFFF', disabled: '#535964' }, // 8.64:1 / 4.65:1 / 11.69:1 ✓ AA+
|
|
203
|
+
},
|
|
204
|
+
buttonSecondary: {
|
|
205
|
+
background: { default: '#131416', hovered: '#2F3237', pressed: '#41454E', focused: '#2F3237', disabled: '#131416' },
|
|
206
|
+
text: { default: '#59B0C4', disabled: '#535964' }, // 7.40:1 ✓ AAA
|
|
207
|
+
border: { default: '#59B0C4', disabled: '#41454E' },
|
|
208
|
+
},
|
|
209
|
+
// Feedback states
|
|
210
|
+
badge: { background: '#41454E', text: '#EBEDEF', border: '#535964' },
|
|
211
|
+
tooltip: { background: '#EBEDEF', text: '#2F3237' },
|
|
212
|
+
overlay: 'rgba(19, 20, 22, 0.75)',
|
|
213
|
+
skeleton: { from: '#2F3237', to: '#41454E' },
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// ──────────────────────────────────────────────
|
|
218
|
+
// Data Visualization Palette
|
|
219
|
+
// ──────────────────────────────────────────────
|
|
220
|
+
|
|
221
|
+
// 10 hues derived from the EV brand palette.
|
|
222
|
+
// Core 4 (teal, sky blue, coral, yellow) + 6 harmonious neighbors.
|
|
223
|
+
// Each has 5 shades: [100-light, 300, 400, base-500, 700-dark]
|
|
224
|
+
export const dataVizPalette = [
|
|
225
|
+
{ name: 'Teal', base: '#00657C', shades: ['#C0E8F2', '#55D9F6', '#3AABB8', '#00657C', '#003E4D'] },
|
|
226
|
+
{ name: 'Sky Blue', base: '#59B0C4', shades: ['#CDE0E5', '#A7CFD8', '#7FBECC', '#59B0C4', '#327E8F'] },
|
|
227
|
+
{ name: 'Ocean', base: '#2563A0', shades: ['#CDDCED', '#7BADD4', '#4D8FC2', '#2563A0', '#193F68'] },
|
|
228
|
+
{ name: 'Coral', base: '#FF5740', shades: ['#F6E6E4', '#F2988C', '#F66855', '#FF5740', '#B31D09'] },
|
|
229
|
+
{ name: 'Terracotta', base: '#C2674A', shades: ['#F0DCD4', '#D9A48E', '#CF8568', '#C2674A', '#7A3D2C'] },
|
|
230
|
+
{ name: 'Yellow', base: '#FED12E', shades: ['#F6F2E4', '#F2DC8D', '#F5D356', '#FED12E', '#9F7F09'] },
|
|
231
|
+
{ name: 'Honey', base: '#D4940B', shades: ['#F5EACE', '#E8C563', '#DCA930', '#D4940B', '#805A06'] },
|
|
232
|
+
{ name: 'Sage', base: '#5A9A6E', shades: ['#D4E8DA', '#9ACBAA', '#74B589', '#5A9A6E', '#376043'] },
|
|
233
|
+
{ name: 'Dusk', base: '#7C6B9E', shades: ['#E4DFF0', '#B5A8CF', '#9788B8', '#7C6B9E', '#4D4263'] },
|
|
234
|
+
{ name: 'Stone', base: '#6B7280', shades: ['#EBEDEF', '#B3BBCC', '#8F9EBC', '#6B7280', '#41454E'] },
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
// ──────────────────────────────────────────────
|
|
238
|
+
// Typography
|
|
239
|
+
// ──────────────────────────────────────────────
|
|
240
|
+
|
|
241
|
+
export const fonts = {
|
|
242
|
+
primary: "'Manrope', sans-serif",
|
|
243
|
+
fallback: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export const fontWeights = {
|
|
247
|
+
regular: 400,
|
|
248
|
+
medium: 500,
|
|
249
|
+
semibold: 600,
|
|
250
|
+
bold: 700,
|
|
251
|
+
extrabold: 800,
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export const fontSizes = {
|
|
255
|
+
xs: '12px',
|
|
256
|
+
sm: '14px',
|
|
257
|
+
base: '16px',
|
|
258
|
+
lg: '18px',
|
|
259
|
+
xl: '20px',
|
|
260
|
+
'2xl': '24px',
|
|
261
|
+
'3xl': '30px',
|
|
262
|
+
'4xl': '36px',
|
|
263
|
+
'5xl': '48px',
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export const lineHeights = {
|
|
267
|
+
tight: 1.25,
|
|
268
|
+
normal: 1.5,
|
|
269
|
+
relaxed: 1.75,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export const letterSpacing = {
|
|
273
|
+
tight: '-0.02em',
|
|
274
|
+
normal: '0',
|
|
275
|
+
wide: '0.05em',
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// Composite text styles — combine size, weight, line-height, and letter-spacing
|
|
279
|
+
// into ready-to-spread objects for inline styles: style={{ ...textStyles.displayTitle }}
|
|
280
|
+
export const textStyles = {
|
|
281
|
+
displayTitle: { fontSize: '48px', fontWeight: 800, lineHeight: 1.1, letterSpacing: '-0.03em' },
|
|
282
|
+
displaySub: { fontSize: '36px', fontWeight: 700, lineHeight: 1.15, letterSpacing: '-0.02em' },
|
|
283
|
+
h1: { fontSize: '30px', fontWeight: 700, lineHeight: 1.25, letterSpacing: '-0.02em' },
|
|
284
|
+
h2: { fontSize: '24px', fontWeight: 700, lineHeight: 1.3, letterSpacing: '-0.01em' },
|
|
285
|
+
h3: { fontSize: '20px', fontWeight: 600, lineHeight: 1.35, letterSpacing: '0' },
|
|
286
|
+
h4: { fontSize: '18px', fontWeight: 600, lineHeight: 1.4, letterSpacing: '0' },
|
|
287
|
+
bodyLg: { fontSize: '18px', fontWeight: 400, lineHeight: 1.6, letterSpacing: '0' },
|
|
288
|
+
body: { fontSize: '16px', fontWeight: 400, lineHeight: 1.5, letterSpacing: '0' },
|
|
289
|
+
bodySm: { fontSize: '14px', fontWeight: 400, lineHeight: 1.5, letterSpacing: '0' },
|
|
290
|
+
label: { fontSize: '14px', fontWeight: 500, lineHeight: 1.4, letterSpacing: '0.01em' },
|
|
291
|
+
labelSm: { fontSize: '12px', fontWeight: 500, lineHeight: 1.4, letterSpacing: '0.02em' },
|
|
292
|
+
caption: { fontSize: '12px', fontWeight: 400, lineHeight: 1.4, letterSpacing: '0.01em' },
|
|
293
|
+
overline: { fontSize: '11px', fontWeight: 700, lineHeight: 1.4, letterSpacing: '0.08em', textTransform: 'uppercase' },
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// ──────────────────────────────────────────────
|
|
297
|
+
// Spacing (4px base unit)
|
|
298
|
+
// ──────────────────────────────────────────────
|
|
299
|
+
|
|
300
|
+
export const spacing = {
|
|
301
|
+
0: '0',
|
|
302
|
+
'050': '2px',
|
|
303
|
+
1: '4px',
|
|
304
|
+
'150': '6px',
|
|
305
|
+
2: '8px',
|
|
306
|
+
3: '12px',
|
|
307
|
+
4: '16px',
|
|
308
|
+
5: '20px',
|
|
309
|
+
6: '24px',
|
|
310
|
+
8: '32px',
|
|
311
|
+
10: '40px',
|
|
312
|
+
12: '48px',
|
|
313
|
+
16: '64px',
|
|
314
|
+
20: '80px',
|
|
315
|
+
24: '96px',
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// ──────────────────────────────────────────────
|
|
319
|
+
// Border Radius
|
|
320
|
+
// ──────────────────────────────────────────────
|
|
321
|
+
|
|
322
|
+
export const borderRadius = {
|
|
323
|
+
none: '0',
|
|
324
|
+
sm: '4px',
|
|
325
|
+
md: '8px',
|
|
326
|
+
lg: '10px',
|
|
327
|
+
xl: '12px',
|
|
328
|
+
'2xl': '16px',
|
|
329
|
+
full: '9999px',
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
// ──────────────────────────────────────────────
|
|
333
|
+
// Shadows & Elevation
|
|
334
|
+
// ──────────────────────────────────────────────
|
|
335
|
+
|
|
336
|
+
export const shadows = {
|
|
337
|
+
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
338
|
+
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
|
|
339
|
+
lg: '0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 10px -4px rgba(0, 0, 0, 0.05)',
|
|
340
|
+
xl: '0 20px 40px -8px rgba(0, 0, 0, 0.12), 0 8px 16px -6px rgba(0, 0, 0, 0.06)',
|
|
341
|
+
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
|
|
342
|
+
glowCoral: '0 0 0 3px rgba(255, 87, 64, 0.25)',
|
|
343
|
+
glowTeal: '0 0 0 3px rgba(0, 101, 124, 0.2)',
|
|
344
|
+
cardHover: '0 12px 32px -4px rgba(0, 0, 0, 0.12), 0 4px 8px -2px rgba(0, 0, 0, 0.04)',
|
|
345
|
+
none: 'none',
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// ──────────────────────────────────────────────
|
|
349
|
+
// Motion
|
|
350
|
+
// ──────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
export const duration = {
|
|
353
|
+
instant: '50ms',
|
|
354
|
+
fast: '120ms', // Micro-interactions: toggles, checkboxes
|
|
355
|
+
normal: '200ms', // Buttons, inputs, small transitions
|
|
356
|
+
slow: '350ms', // Panels, cards, modals
|
|
357
|
+
slower: '500ms', // Page transitions, complex orchestration
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
export const easing = {
|
|
361
|
+
default: 'cubic-bezier(0.2, 0, 0, 1)', // General-purpose (Material 3 standard)
|
|
362
|
+
enter: 'cubic-bezier(0, 0, 0.2, 1)', // Elements appearing (decelerate)
|
|
363
|
+
exit: 'cubic-bezier(0.4, 0, 1, 1)', // Elements leaving (accelerate)
|
|
364
|
+
spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)', // Playful overshoot — buttons, badges
|
|
365
|
+
linear: 'linear',
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// ──────────────────────────────────────────────
|
|
369
|
+
// Focus Ring
|
|
370
|
+
// ──────────────────────────────────────────────
|
|
371
|
+
|
|
372
|
+
export const focus = {
|
|
373
|
+
ring: '0 0 0 2px #FFFFFF, 0 0 0 4px #00657C', // White gap + brand muted blue (6.66:1 on white)
|
|
374
|
+
ringDark: '0 0 0 2px #131416, 0 0 0 4px #59B0C4', // Dark gap + light blue (6.84:1 on dark)
|
|
375
|
+
ringCoral: '0 0 0 2px #FFFFFF, 0 0 0 4px #FF5740', // Coral variant for pillar contexts
|
|
376
|
+
offset: '2px',
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
// ──────────────────────────────────────────────
|
|
380
|
+
// Z-Index Scale
|
|
381
|
+
// ──────────────────────────────────────────────
|
|
382
|
+
|
|
383
|
+
export const zIndex = {
|
|
384
|
+
hide: -1,
|
|
385
|
+
base: 0,
|
|
386
|
+
dropdown: 10,
|
|
387
|
+
sticky: 20,
|
|
388
|
+
header: 30,
|
|
389
|
+
overlay: 40,
|
|
390
|
+
modal: 50,
|
|
391
|
+
toast: 60,
|
|
392
|
+
tooltip: 70,
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// ──────────────────────────────────────────────
|
|
396
|
+
// Opacity
|
|
397
|
+
// ──────────────────────────────────────────────
|
|
398
|
+
|
|
399
|
+
export const opacity = {
|
|
400
|
+
disabled: 0.4,
|
|
401
|
+
muted: 0.6,
|
|
402
|
+
subtle: 0.8,
|
|
403
|
+
full: 1,
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// ──────────────────────────────────────────────
|
|
407
|
+
// Breakpoints
|
|
408
|
+
// ──────────────────────────────────────────────
|
|
409
|
+
|
|
410
|
+
export const breakpoints = {
|
|
411
|
+
sm: '640px',
|
|
412
|
+
md: '768px',
|
|
413
|
+
lg: '1024px',
|
|
414
|
+
xl: '1280px',
|
|
415
|
+
};
|