@oneqode/design-system 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/css/recipes.css +61 -0
- package/build/css/remake/tokens.css +376 -41
- package/build/md/design-tokens.md +111 -2
- package/package.json +4 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* OneQode Design System - Recipe CSS
|
|
3
|
+
*
|
|
4
|
+
* Hand-authored CSS patterns that compose design tokens into stable class names.
|
|
5
|
+
* Patterns are added as individual files (button.css, card.css, etc.) and
|
|
6
|
+
* concatenated into build/css/recipes.css by scripts/build-tokens.mjs.
|
|
7
|
+
*
|
|
8
|
+
* See CLAUDE.md ("Adding a New Recipe") for the workflow.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* Icon recipe
|
|
13
|
+
*
|
|
14
|
+
* Wraps a Lucide-style stroke SVG (or any SVG that uses stroke="currentColor")
|
|
15
|
+
* and exposes size, stroke weight, and color intent through composable
|
|
16
|
+
* modifier classes. The host element is a <span>; the <svg> sits inside.
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* <span class="oq-icon"><svg ...></svg></span>
|
|
20
|
+
* <span class="oq-icon oq-icon--lg oq-icon--accent"><svg ...></svg></span>
|
|
21
|
+
*
|
|
22
|
+
* SVG must:
|
|
23
|
+
* - use stroke="currentColor" (Lucide default)
|
|
24
|
+
* - omit width/height/stroke-width (the recipe owns these)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
.oq-icon {
|
|
28
|
+
display: inline-block;
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
width: var(--component-icon-size-md);
|
|
31
|
+
height: var(--component-icon-size-md);
|
|
32
|
+
color: var(--color-icon-default);
|
|
33
|
+
vertical-align: -0.125em;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.oq-icon > svg {
|
|
37
|
+
display: block;
|
|
38
|
+
width: 100%;
|
|
39
|
+
height: 100%;
|
|
40
|
+
stroke: currentColor;
|
|
41
|
+
stroke-width: var(--component-icon-stroke-regular);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Sizes */
|
|
45
|
+
.oq-icon--xs { width: var(--component-icon-size-xs); height: var(--component-icon-size-xs); }
|
|
46
|
+
.oq-icon--sm { width: var(--component-icon-size-sm); height: var(--component-icon-size-sm); }
|
|
47
|
+
.oq-icon--lg { width: var(--component-icon-size-lg); height: var(--component-icon-size-lg); }
|
|
48
|
+
.oq-icon--xl { width: var(--component-icon-size-xl); height: var(--component-icon-size-xl); }
|
|
49
|
+
|
|
50
|
+
/* Stroke weights */
|
|
51
|
+
.oq-icon--thin > svg { stroke-width: var(--component-icon-stroke-thin); }
|
|
52
|
+
.oq-icon--bold > svg { stroke-width: var(--component-icon-stroke-bold); }
|
|
53
|
+
|
|
54
|
+
/* Color intents */
|
|
55
|
+
.oq-icon--accent { color: var(--color-icon-accent); }
|
|
56
|
+
.oq-icon--action { color: var(--color-icon-action); }
|
|
57
|
+
.oq-icon--subtle { color: var(--color-icon-subtle); }
|
|
58
|
+
.oq-icon--disabled { color: var(--color-icon-disabled); }
|
|
59
|
+
.oq-icon--inverse { color: var(--color-icon-inverse); }
|
|
60
|
+
|
|
61
|
+
.oq-icon--action:hover { color: var(--color-icon-action-hover); }
|
|
@@ -3,30 +3,178 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
:root {
|
|
6
|
-
--color-border-
|
|
7
|
-
--color-
|
|
8
|
-
--color-
|
|
9
|
-
--color-
|
|
10
|
-
--color-
|
|
11
|
-
--color-
|
|
12
|
-
--color-
|
|
13
|
-
--color-
|
|
14
|
-
--color-
|
|
15
|
-
--color-
|
|
16
|
-
--color-
|
|
17
|
-
--color-
|
|
18
|
-
--color-
|
|
19
|
-
--color-
|
|
20
|
-
--color-
|
|
21
|
-
--color-
|
|
22
|
-
--color-
|
|
23
|
-
--color-
|
|
24
|
-
--color-
|
|
25
|
-
--color-
|
|
26
|
-
--color-
|
|
27
|
-
--color-
|
|
28
|
-
--color-
|
|
29
|
-
--color-
|
|
6
|
+
--color-border-accent: #2a8dff; /** Accent border - feature highlights */
|
|
7
|
+
--color-border-action: #2a8dff; /** Action border - CTA outlines */
|
|
8
|
+
--color-border-action-hover: #4aa2ff; /** Action border - hover state */
|
|
9
|
+
--color-border-default: #1f1f1f; /** Default border */
|
|
10
|
+
--color-border-disabled: #1f1f1f; /** Disabled component border */
|
|
11
|
+
--color-border-error: #ef4444; /** Error border */
|
|
12
|
+
--color-border-focus: #2a8dff; /** Focus ring border */
|
|
13
|
+
--color-border-information: #2a8dff; /** Informational border */
|
|
14
|
+
--color-border-inverse: #e0e0e0; /** Border on inverse surfaces */
|
|
15
|
+
--color-border-subtle: #000000; /** Subtle border - hairline dividers */
|
|
16
|
+
--color-border-success: #22c55e; /** Success border */
|
|
17
|
+
--color-border-warning: #f59e0b; /** Warning border */
|
|
18
|
+
--color-blue-50: #eef7ff;
|
|
19
|
+
--color-blue-100: #d9ecff;
|
|
20
|
+
--color-blue-200: #b6daff;
|
|
21
|
+
--color-blue-300: #85c2ff;
|
|
22
|
+
--color-blue-400: #4aa2ff;
|
|
23
|
+
--color-blue-500: #2a8dff; /** OneQode brand blue - primary CTA, links, active states (dark mode) */
|
|
24
|
+
--color-blue-600: #1774e0; /** OneQode brand blue - primary CTA, links, active states (light mode) */
|
|
25
|
+
--color-blue-700: #125bb5;
|
|
26
|
+
--color-blue-800: #124a91;
|
|
27
|
+
--color-blue-900: #133f73;
|
|
28
|
+
--color-blue-950: #0b264b;
|
|
29
|
+
--color-red-50: #fef2f2;
|
|
30
|
+
--color-red-100: #fee2e2;
|
|
31
|
+
--color-red-200: #fecaca;
|
|
32
|
+
--color-red-300: #fca5a5;
|
|
33
|
+
--color-red-400: #f87171;
|
|
34
|
+
--color-red-500: #ef4444;
|
|
35
|
+
--color-red-600: #dc2626;
|
|
36
|
+
--color-red-700: #b91c1c;
|
|
37
|
+
--color-red-800: #991b1b;
|
|
38
|
+
--color-red-900: #7f1d1d;
|
|
39
|
+
--color-red-950: #450a0a;
|
|
40
|
+
--color-green-50: #f8fdf4;
|
|
41
|
+
--color-green-100: #dcfce7;
|
|
42
|
+
--color-green-200: #bbf7d0;
|
|
43
|
+
--color-green-300: #86efac;
|
|
44
|
+
--color-green-400: #4ade80;
|
|
45
|
+
--color-green-500: #22c55e;
|
|
46
|
+
--color-green-600: #16a34a;
|
|
47
|
+
--color-green-700: #15803d;
|
|
48
|
+
--color-green-800: #166534;
|
|
49
|
+
--color-green-900: #14532d;
|
|
50
|
+
--color-green-950: #052e16;
|
|
51
|
+
--color-amber-50: #fffbeb;
|
|
52
|
+
--color-amber-100: #fef3c7;
|
|
53
|
+
--color-amber-200: #fde68a;
|
|
54
|
+
--color-amber-300: #fcd34d;
|
|
55
|
+
--color-amber-400: #fbbf24;
|
|
56
|
+
--color-amber-500: #f59e0b;
|
|
57
|
+
--color-amber-600: #d97706;
|
|
58
|
+
--color-amber-700: #b45309;
|
|
59
|
+
--color-amber-800: #92400e;
|
|
60
|
+
--color-amber-900: #78350f;
|
|
61
|
+
--color-amber-950: #451a03;
|
|
62
|
+
--color-neutral-50: #fafafa;
|
|
63
|
+
--color-neutral-100: #f2f2f2;
|
|
64
|
+
--color-neutral-200: #e0e0e0;
|
|
65
|
+
--color-neutral-300: #c7c7c7;
|
|
66
|
+
--color-neutral-400: #9e9e9e;
|
|
67
|
+
--color-neutral-500: #777777;
|
|
68
|
+
--color-neutral-600: #555555;
|
|
69
|
+
--color-neutral-700: #333333;
|
|
70
|
+
--color-neutral-800: #1f1f1f;
|
|
71
|
+
--color-neutral-900: #000000;
|
|
72
|
+
--color-neutral-950: #050505;
|
|
73
|
+
--color-black: #000000;
|
|
74
|
+
--color-white: #ffffff;
|
|
75
|
+
--color-surface-accent: #2a8dff; /** Brand-accent surface - feature highlights, accent fills */
|
|
76
|
+
--color-surface-action: #2a8dff; /** Primary action surface - CTA buttons, active states */
|
|
77
|
+
--color-surface-action-hover: #4aa2ff; /** Primary action surface - hover state */
|
|
78
|
+
--color-surface-bg: #000000; /** Page background - foundation black/white */
|
|
79
|
+
--color-surface-default: #050505; /** Default card/component surface */
|
|
80
|
+
--color-surface-disabled: #000000; /** Disabled component surface */
|
|
81
|
+
--color-surface-inverse: #ffffff; /** Inverted surface - white card on dark, black card on light */
|
|
82
|
+
--color-surface-raised: #000000; /** Raised surface - modals, popovers, ghost-button hover */
|
|
83
|
+
--color-alias-accent-50: #eef7ff;
|
|
84
|
+
--color-alias-accent-100: #d9ecff;
|
|
85
|
+
--color-alias-accent-200: #b6daff;
|
|
86
|
+
--color-alias-accent-300: #85c2ff;
|
|
87
|
+
--color-alias-accent-400: #4aa2ff;
|
|
88
|
+
--color-alias-accent-500: #2a8dff;
|
|
89
|
+
--color-alias-accent-600: #1774e0;
|
|
90
|
+
--color-alias-accent-700: #125bb5;
|
|
91
|
+
--color-alias-accent-800: #124a91;
|
|
92
|
+
--color-alias-accent-900: #133f73;
|
|
93
|
+
--color-alias-accent-950: #0b264b;
|
|
94
|
+
--color-alias-accent-default: #2a8dff;
|
|
95
|
+
--color-alias-information-50: #eef7ff;
|
|
96
|
+
--color-alias-information-100: #d9ecff;
|
|
97
|
+
--color-alias-information-200: #b6daff;
|
|
98
|
+
--color-alias-information-300: #85c2ff;
|
|
99
|
+
--color-alias-information-400: #4aa2ff;
|
|
100
|
+
--color-alias-information-500: #2a8dff;
|
|
101
|
+
--color-alias-information-600: #1774e0;
|
|
102
|
+
--color-alias-information-700: #125bb5;
|
|
103
|
+
--color-alias-information-800: #124a91;
|
|
104
|
+
--color-alias-information-900: #133f73;
|
|
105
|
+
--color-alias-information-950: #0b264b;
|
|
106
|
+
--color-alias-information-default: #1774e0;
|
|
107
|
+
--color-alias-error-50: #fef2f2;
|
|
108
|
+
--color-alias-error-100: #fee2e2;
|
|
109
|
+
--color-alias-error-200: #fecaca;
|
|
110
|
+
--color-alias-error-300: #fca5a5;
|
|
111
|
+
--color-alias-error-400: #f87171;
|
|
112
|
+
--color-alias-error-500: #ef4444;
|
|
113
|
+
--color-alias-error-600: #dc2626;
|
|
114
|
+
--color-alias-error-700: #b91c1c;
|
|
115
|
+
--color-alias-error-800: #991b1b;
|
|
116
|
+
--color-alias-error-900: #7f1d1d;
|
|
117
|
+
--color-alias-error-950: #450a0a;
|
|
118
|
+
--color-alias-error-default: #dc2626;
|
|
119
|
+
--color-alias-success-50: #f8fdf4;
|
|
120
|
+
--color-alias-success-100: #dcfce7;
|
|
121
|
+
--color-alias-success-200: #bbf7d0;
|
|
122
|
+
--color-alias-success-300: #86efac;
|
|
123
|
+
--color-alias-success-400: #4ade80;
|
|
124
|
+
--color-alias-success-500: #22c55e;
|
|
125
|
+
--color-alias-success-600: #16a34a;
|
|
126
|
+
--color-alias-success-700: #15803d;
|
|
127
|
+
--color-alias-success-800: #166534;
|
|
128
|
+
--color-alias-success-900: #14532d;
|
|
129
|
+
--color-alias-success-950: #052e16;
|
|
130
|
+
--color-alias-success-default: #16a34a;
|
|
131
|
+
--color-alias-warning-50: #fffbeb;
|
|
132
|
+
--color-alias-warning-100: #fef3c7;
|
|
133
|
+
--color-alias-warning-200: #fde68a;
|
|
134
|
+
--color-alias-warning-300: #fcd34d;
|
|
135
|
+
--color-alias-warning-400: #fbbf24;
|
|
136
|
+
--color-alias-warning-500: #f59e0b;
|
|
137
|
+
--color-alias-warning-600: #d97706;
|
|
138
|
+
--color-alias-warning-700: #b45309;
|
|
139
|
+
--color-alias-warning-800: #92400e;
|
|
140
|
+
--color-alias-warning-900: #78350f;
|
|
141
|
+
--color-alias-warning-950: #451a03;
|
|
142
|
+
--color-alias-warning-default: #d97706;
|
|
143
|
+
--color-alias-neutral-50: #fafafa;
|
|
144
|
+
--color-alias-neutral-100: #f2f2f2;
|
|
145
|
+
--color-alias-neutral-200: #e0e0e0;
|
|
146
|
+
--color-alias-neutral-300: #c7c7c7;
|
|
147
|
+
--color-alias-neutral-400: #9e9e9e;
|
|
148
|
+
--color-alias-neutral-500: #777777;
|
|
149
|
+
--color-alias-neutral-600: #555555;
|
|
150
|
+
--color-alias-neutral-700: #333333;
|
|
151
|
+
--color-alias-neutral-800: #1f1f1f;
|
|
152
|
+
--color-alias-neutral-900: #000000;
|
|
153
|
+
--color-alias-neutral-950: #050505;
|
|
154
|
+
--color-alias-black: #000000;
|
|
155
|
+
--color-alias-white: #ffffff;
|
|
156
|
+
--color-icon-accent: #2a8dff; /** Accent icon */
|
|
157
|
+
--color-icon-action: #2a8dff; /** Action icon - links, interactive controls */
|
|
158
|
+
--color-icon-action-hover: #4aa2ff; /** Action icon - hover state */
|
|
159
|
+
--color-icon-default: #ffffff; /** Default icon - maximum contrast */
|
|
160
|
+
--color-icon-disabled: #555555; /** Disabled icon */
|
|
161
|
+
--color-icon-inverse: #000000; /** Icon on inverse surfaces */
|
|
162
|
+
--color-icon-on-action: #ffffff; /** Icon rendered on action surfaces - always white, mode-agnostic */
|
|
163
|
+
--color-icon-subtle: #777777; /** Subtle/auxiliary icon - mid grey, mode-agnostic */
|
|
164
|
+
--color-text-accent: #2a8dff; /** Accent text - feature highlights */
|
|
165
|
+
--color-text-action: #2a8dff; /** Action text - links, interactive labels */
|
|
166
|
+
--color-text-action-hover: #4aa2ff; /** Action text - hover state */
|
|
167
|
+
--color-text-body: #c7c7c7; /** Default body text */
|
|
168
|
+
--color-text-disabled: #555555; /** Disabled text */
|
|
169
|
+
--color-text-error: #f87171; /** Error/destructive text */
|
|
170
|
+
--color-text-headings: #ffffff; /** Heading text - maximum contrast */
|
|
171
|
+
--color-text-information: #2a8dff; /** Informational text */
|
|
172
|
+
--color-text-inverse: #000000; /** Text on inverse surfaces */
|
|
173
|
+
--color-text-on-action: #ffffff; /** Text rendered on action surfaces - always white, mode-agnostic */
|
|
174
|
+
--color-text-on-media-secondary: #ffffffcc; /** Secondary/body text on image or media backgrounds - white at 80% opacity, mode-agnostic */
|
|
175
|
+
--color-text-success: #4ade80; /** Success/positive text */
|
|
176
|
+
--color-text-tertiary: #777777; /** Tertiary/auxiliary text - mid grey, mode-agnostic */
|
|
177
|
+
--color-text-warning: #fbbf24; /** Warning/caution text */
|
|
30
178
|
--radius: 0.5rem; /** Default border radius for cards and inputs */
|
|
31
179
|
--shadow-dropdown: 0 8px 40px rgba(255, 255, 255, 0.06); /** Dropdown panel shadow */
|
|
32
180
|
--shadow-avatar-glow: inset 0 11.46px 22.92px #ffffff14, inset 0 2.87px 2.87px #ffffff59; /** Avatar/icon glow effect */
|
|
@@ -39,26 +187,213 @@
|
|
|
39
187
|
--container-compact: 650px; /** Tight text blocks, centered descriptions */
|
|
40
188
|
--container-content: 600px; /** Paragraph descriptions, subtitles */
|
|
41
189
|
--spacing-section: 5rem; /** Standard spacing between page sections */
|
|
42
|
-
--
|
|
43
|
-
--
|
|
190
|
+
--spacing-section-lg: 10rem; /** Large section block padding - 160px (used for major page sections per Figma) */
|
|
191
|
+
--spacing-inset: 1.5rem; /** Standard inner padding for sections and cards - 24px */
|
|
192
|
+
--font-sans: Space Grotesk, system-ui, sans-serif; /** Body text font stack */
|
|
193
|
+
--font-display: Saans, system-ui, sans-serif; /** Heading/display font stack */
|
|
44
194
|
--font-mono: "Fira Code", ui-monospace, monospace; /** Code/monospace font stack */
|
|
45
|
-
--font-size-
|
|
46
|
-
--font-size-
|
|
47
|
-
--font-size-
|
|
48
|
-
--font-size-
|
|
49
|
-
--font-size-
|
|
50
|
-
--font-size-
|
|
51
|
-
--font-size-
|
|
52
|
-
--font-size-
|
|
53
|
-
--font-size-
|
|
54
|
-
--font-size-
|
|
55
|
-
--font-size-
|
|
56
|
-
--font-size-
|
|
57
|
-
--font-size-
|
|
58
|
-
--font-size-
|
|
59
|
-
--font-size-display: 4.5rem; /** 72px - maximum display heading */
|
|
195
|
+
--font-size-12: 0.75rem; /** 12px - text-xs (caption/legal/metadata), text-mono (eyebrow/tag/code) */
|
|
196
|
+
--font-size-14: 0.875rem; /** 14px - text-sm (body small / dense UI) */
|
|
197
|
+
--font-size-16: 1rem; /** 16px - text-md (body default) */
|
|
198
|
+
--font-size-18: 1.125rem; /** 18px - text-lg (lead paragraph), h6 mobile */
|
|
199
|
+
--font-size-20: 1.25rem; /** 20px - h6 desktop */
|
|
200
|
+
--font-size-22: 1.375rem; /** 22px - h5 mobile */
|
|
201
|
+
--font-size-24: 1.5rem; /** 24px - h5 desktop */
|
|
202
|
+
--font-size-26: 1.625rem; /** 26px - h4 mobile */
|
|
203
|
+
--font-size-28: 1.75rem; /** 28px - h4 desktop */
|
|
204
|
+
--font-size-32: 2rem; /** 32px - h3 mobile and desktop */
|
|
205
|
+
--font-size-40: 2.5rem; /** 40px - h2 mobile */
|
|
206
|
+
--font-size-44: 2.75rem; /** 44px - h2 desktop */
|
|
207
|
+
--font-size-52: 3.25rem; /** 52px - h1 mobile */
|
|
208
|
+
--font-size-64: 4rem; /** 64px - h1 desktop */
|
|
60
209
|
--font-weight-normal: 400; /** Normal body text */
|
|
61
210
|
--font-weight-medium: 500; /** Medium emphasis */
|
|
62
211
|
--font-weight-semibold: 600; /** Buttons, labels, subheadings */
|
|
63
212
|
--font-weight-bold: 700; /** Headings, strong emphasis */
|
|
213
|
+
--font-letter-spacing-heading: -0.02em; /** Desktop headings (H1-H6) - -2% tracking */
|
|
214
|
+
--font-letter-spacing-body: -0.01em; /** Body text (text-lg, text-md, text-sm, text-xs) - -1% tracking */
|
|
215
|
+
--font-letter-spacing-mono: 0; /** Mono (text-mono) - no tracking */
|
|
216
|
+
--font-letter-spacing-h1-mobile: -0.0385em; /** H1 mobile - -2/52 */
|
|
217
|
+
--font-letter-spacing-h2-mobile: -0.0375em; /** H2 mobile - -1.5/40 */
|
|
218
|
+
--font-letter-spacing-h3-mobile: -0.03125em; /** H3 mobile - -1/32 */
|
|
219
|
+
--font-letter-spacing-h4-mobile: -0.0192em; /** H4 mobile - -0.5/26 */
|
|
220
|
+
--font-letter-spacing-h5-mobile: -0.0114em; /** H5 mobile - -0.25/22 */
|
|
221
|
+
--font-letter-spacing-h6-mobile: 0; /** H6 mobile - none specified */
|
|
222
|
+
--font-line-height-tight: 1.2; /** Desktop headings (H2-H6) - 1.2 ratio */
|
|
223
|
+
--font-line-height-body: 1.5; /** All body text (text-lg, text-md, text-sm, text-xs, text-mono) - 1.5 ratio */
|
|
224
|
+
--font-line-height-h1-desktop: 1.0625; /** H1 desktop - 68/64 */
|
|
225
|
+
--font-line-height-h1-mobile: 1.0769; /** H1 mobile - 56/52 */
|
|
226
|
+
--font-line-height-h2-mobile: 1.1; /** H2 mobile - 44/40 */
|
|
227
|
+
--font-line-height-h3-mobile: 1.125; /** H3 mobile - 36/32 */
|
|
228
|
+
--font-line-height-h4-mobile: 1.2308; /** H4 mobile - 32/26 */
|
|
229
|
+
--font-line-height-h5-mobile: 1.2727; /** H5 mobile - 28/22 */
|
|
230
|
+
--font-line-height-h6-mobile: 1.3333; /** H6 mobile - 24/18 */
|
|
231
|
+
--component-badge-background: #ffffff; /** Annotation chip background - white */
|
|
232
|
+
--component-badge-text: #111111; /** Annotation chip text - near black */
|
|
233
|
+
--component-badge-radius: 9999px; /** Annotation chip radius - full pill */
|
|
234
|
+
--component-button-radius: 4px; /** Button border radius */
|
|
235
|
+
--component-button-padding-x: 14px; /** Button horizontal padding */
|
|
236
|
+
--component-button-padding-top: 14px; /** Button top padding */
|
|
237
|
+
--component-button-padding-bottom: 15px; /** Button bottom padding - 1px asymmetric to optically center the label */
|
|
238
|
+
--component-button-gap: 8px; /** Gap between icon and label */
|
|
239
|
+
--component-button-font-weight: 700; /** Button label weight */
|
|
240
|
+
--component-button-default-bg: #ffffff; /** Button - default variant background (solid white CTA) */
|
|
241
|
+
--component-button-default-text: #000000; /** Button - default variant label */
|
|
242
|
+
--component-button-default-icon: #000000; /** Button - default variant icon */
|
|
243
|
+
--component-button-outline-border: rgba(255, 255, 255, 0.12); /** Button - outline variant border (12% white hairline) */
|
|
244
|
+
--component-button-outline-border-hover: #e0e0e0; /** Button - outline variant border, hover state */
|
|
245
|
+
--component-button-outline-text: #ffffff; /** Button - outline variant label */
|
|
246
|
+
--component-button-outline-icon: #ffffff; /** Button - outline variant icon */
|
|
247
|
+
--component-button-shade-bg: rgba(255, 255, 255, 0.04); /** Button - shade variant background (4% white wash, paired with backdrop blur) */
|
|
248
|
+
--component-button-shade-hover-bg: rgba(255, 255, 255, 0.08); /** Button - shade variant background, hover state */
|
|
249
|
+
--component-button-shade-blur: 6px; /** Button - shade variant backdrop-filter blur radius */
|
|
250
|
+
--component-button-shade-text: #ffffff; /** Button - shade variant label */
|
|
251
|
+
--component-button-shade-icon: #ffffff; /** Button - shade variant icon */
|
|
252
|
+
--component-button-accent-bg: #2a8dff; /** Button - accent variant background (brand blue CTA) */
|
|
253
|
+
--component-button-accent-hover-bg: #4aa2ff; /** Button - accent variant background, hover state */
|
|
254
|
+
--component-button-accent-text: #ffffff; /** Button - accent variant label */
|
|
255
|
+
--component-button-accent-icon: #ffffff; /** Button - accent variant icon */
|
|
256
|
+
--component-button-ghost-text: #ffffff; /** Button - ghost variant label (no fill, no border) */
|
|
257
|
+
--component-button-ghost-icon: #ffffff; /** Button - ghost variant icon */
|
|
258
|
+
--component-button-disabled-bg: #0d0d0d; /** Button - disabled state background, shared across all variants */
|
|
259
|
+
--component-button-disabled-text: #555555; /** Button - disabled state label */
|
|
260
|
+
--component-button-disabled-icon: #555555; /** Button - disabled state icon */
|
|
261
|
+
--component-grid-divider-color: #1f1f1f; /** Hairline divider between grid sections (logo strip top/bottom, card grid) */
|
|
262
|
+
--component-grid-divider-width: 1px; /** Hairline divider thickness */
|
|
263
|
+
--component-grid-crosshair-color: #1f1f1f; /** Decorative + crosshair at grid corners */
|
|
264
|
+
--component-grid-crosshair-size: 12px; /** Crosshair glyph size */
|
|
265
|
+
--component-grid-crosshair-stroke: 1px; /** Crosshair stroke thickness */
|
|
266
|
+
--component-icon-size-xs: 12px; /** Icon size - inline metadata, dense tables */
|
|
267
|
+
--component-icon-size-sm: 14px; /** Icon size - inline with body text */
|
|
268
|
+
--component-icon-size-md: 16px; /** Icon size - default UI controls, links */
|
|
269
|
+
--component-icon-size-lg: 20px; /** Icon size - buttons, list items */
|
|
270
|
+
--component-icon-size-xl: 24px; /** Icon size - hero, feature blocks (matches Figma 24px canvas) */
|
|
271
|
+
--component-icon-stroke-thin: 1.5; /** Icon stroke width - airy, decorative */
|
|
272
|
+
--component-icon-stroke-regular: 2; /** Icon stroke width - default (Lucide native) */
|
|
273
|
+
--component-icon-stroke-bold: 2.5; /** Icon stroke width - emphasis, comparison glyphs */
|
|
274
|
+
--component-tag-default-bg: #000000; /** Mono tag - default variant background (dark fill) */
|
|
275
|
+
--component-tag-default-text: #ffffff; /** Mono tag - default variant text (white) */
|
|
276
|
+
--component-tag-default-border: transparent; /** Mono tag - default variant has no border */
|
|
277
|
+
--component-tag-accent-bg: #2a8dff; /** Mono tag - accent variant background (brand blue) */
|
|
278
|
+
--component-tag-accent-text: #ffffff; /** Mono tag - accent variant text (white) */
|
|
279
|
+
--component-tag-accent-border: transparent; /** Mono tag - accent variant has no border */
|
|
280
|
+
--component-tag-outline-bg: transparent; /** Mono tag - outline variant has no fill */
|
|
281
|
+
--component-tag-outline-text: #ffffff; /** Mono tag - outline variant text (white) */
|
|
282
|
+
--component-tag-outline-border: #1f1f1f; /** Mono tag - outline variant border color */
|
|
283
|
+
--gradient-card-overlay: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 100%); /** Bottom-fade scrim on image cards (feature triptych) for text legibility */
|
|
284
|
+
--gradient-hero-overlay: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.7) 100%); /** Top-to-bottom darken on hero imagery - keeps headline legible without flattening the photo */
|
|
285
|
+
--pattern-hatch: repeating-linear-gradient(45deg, transparent 0 4px, rgba(255, 255, 255, 0.06) 4px 5px); /** Diagonal hairline hatch decoration - section frame on case studies and feature card borders */
|
|
286
|
+
--motion-duration-fast: 150ms; /** Snappy interactions - button/link hover, icon swaps */
|
|
287
|
+
--motion-duration-base: 250ms; /** Default UI transition - default for most state changes */
|
|
288
|
+
--motion-duration-slow: 400ms; /** Deliberate transition - card/image reveals, dropdown open */
|
|
289
|
+
--motion-easing-standard: cubic-bezier(0.4, 0, 0.2, 1); /** Standard ease - balanced acceleration/deceleration for most transitions */
|
|
290
|
+
--motion-easing-out: cubic-bezier(0, 0, 0.2, 1); /** Ease-out - elements entering or settling into final state */
|
|
291
|
+
--motion-easing-in: cubic-bezier(0.4, 0, 1, 1); /** Ease-in - elements leaving the screen */
|
|
292
|
+
|
|
293
|
+
/* Typography roles - mobile defaults; desktop overrides at min-width: 768px */
|
|
294
|
+
--type-h1-size: 3.25rem;
|
|
295
|
+
--type-h1-line-height: 1.0769;
|
|
296
|
+
--type-h1-letter-spacing: -0.0385em;
|
|
297
|
+
--type-h2-size: 2.5rem;
|
|
298
|
+
--type-h2-line-height: 1.1;
|
|
299
|
+
--type-h2-letter-spacing: -0.0375em;
|
|
300
|
+
--type-h3-size: 2rem;
|
|
301
|
+
--type-h3-line-height: 1.125;
|
|
302
|
+
--type-h3-letter-spacing: -0.03125em;
|
|
303
|
+
--type-h4-size: 1.625rem;
|
|
304
|
+
--type-h4-line-height: 1.2308;
|
|
305
|
+
--type-h4-letter-spacing: -0.0192em;
|
|
306
|
+
--type-h5-size: 1.375rem;
|
|
307
|
+
--type-h5-line-height: 1.2727;
|
|
308
|
+
--type-h5-letter-spacing: -0.0114em;
|
|
309
|
+
--type-h6-size: 1.125rem;
|
|
310
|
+
--type-h6-line-height: 1.3333;
|
|
311
|
+
--type-h6-letter-spacing: 0;
|
|
312
|
+
--type-text-lg-size: 1.125rem;
|
|
313
|
+
--type-text-lg-line-height: 1.5;
|
|
314
|
+
--type-text-lg-letter-spacing: -0.01em;
|
|
315
|
+
--type-text-md-size: 1rem;
|
|
316
|
+
--type-text-md-line-height: 1.5;
|
|
317
|
+
--type-text-md-letter-spacing: -0.01em;
|
|
318
|
+
--type-text-sm-size: 0.875rem;
|
|
319
|
+
--type-text-sm-line-height: 1.5;
|
|
320
|
+
--type-text-sm-letter-spacing: -0.01em;
|
|
321
|
+
--type-text-xs-size: 0.75rem;
|
|
322
|
+
--type-text-xs-line-height: 1.5;
|
|
323
|
+
--type-text-xs-letter-spacing: -0.01em;
|
|
324
|
+
--type-text-mono-size: 0.75rem;
|
|
325
|
+
--type-text-mono-line-height: 1.5;
|
|
326
|
+
--type-text-mono-letter-spacing: 0;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
/* Light mode overrides - opt in via [data-theme="light"] on any ancestor element. */
|
|
331
|
+
[data-theme="light"] {
|
|
332
|
+
--color-border-accent: #1774e0;
|
|
333
|
+
--color-border-action: #1774e0;
|
|
334
|
+
--color-border-action-hover: #125bb5;
|
|
335
|
+
--color-border-default: #e0e0e0;
|
|
336
|
+
--color-border-disabled: #e0e0e0;
|
|
337
|
+
--color-border-error: #dc2626;
|
|
338
|
+
--color-border-focus: #1774e0;
|
|
339
|
+
--color-border-information: #1774e0;
|
|
340
|
+
--color-border-inverse: #1f1f1f;
|
|
341
|
+
--color-border-subtle: #f2f2f2;
|
|
342
|
+
--color-border-success: #16a34a;
|
|
343
|
+
--color-border-warning: #d97706;
|
|
344
|
+
--color-surface-accent: #1774e0;
|
|
345
|
+
--color-surface-action: #1774e0;
|
|
346
|
+
--color-surface-action-hover: #125bb5;
|
|
347
|
+
--color-surface-bg: #ffffff;
|
|
348
|
+
--color-surface-default: #ffffff;
|
|
349
|
+
--color-surface-disabled: #f2f2f2;
|
|
350
|
+
--color-surface-inverse: #000000;
|
|
351
|
+
--color-surface-raised: #fafafa;
|
|
352
|
+
--color-icon-accent: #1774e0;
|
|
353
|
+
--color-icon-action: #1774e0;
|
|
354
|
+
--color-icon-action-hover: #125bb5;
|
|
355
|
+
--color-icon-default: #000000;
|
|
356
|
+
--color-icon-disabled: #9e9e9e;
|
|
357
|
+
--color-icon-inverse: #ffffff;
|
|
358
|
+
--color-text-accent: #1774e0;
|
|
359
|
+
--color-text-action: #1774e0;
|
|
360
|
+
--color-text-action-hover: #125bb5;
|
|
361
|
+
--color-text-body: #333333;
|
|
362
|
+
--color-text-disabled: #9e9e9e;
|
|
363
|
+
--color-text-error: #dc2626;
|
|
364
|
+
--color-text-headings: #000000;
|
|
365
|
+
--color-text-information: #1774e0;
|
|
366
|
+
--color-text-inverse: #ffffff;
|
|
367
|
+
--color-text-success: #16a34a;
|
|
368
|
+
--color-text-warning: #d97706;
|
|
369
|
+
--component-button-accent-bg: #1774e0;
|
|
370
|
+
--component-button-accent-hover-bg: #125bb5;
|
|
371
|
+
--component-grid-divider-color: #e0e0e0;
|
|
372
|
+
--component-grid-crosshair-color: #e0e0e0;
|
|
373
|
+
--component-tag-default-bg: #fafafa;
|
|
374
|
+
--component-tag-accent-bg: #1774e0;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
@media (min-width: 768px) {
|
|
379
|
+
:root {
|
|
380
|
+
--type-h1-size: 4rem;
|
|
381
|
+
--type-h1-line-height: 1.0625;
|
|
382
|
+
--type-h1-letter-spacing: -0.02em;
|
|
383
|
+
--type-h2-size: 2.75rem;
|
|
384
|
+
--type-h2-line-height: 1.2;
|
|
385
|
+
--type-h2-letter-spacing: -0.02em;
|
|
386
|
+
--type-h3-size: 2rem;
|
|
387
|
+
--type-h3-line-height: 1.2;
|
|
388
|
+
--type-h3-letter-spacing: -0.02em;
|
|
389
|
+
--type-h4-size: 1.75rem;
|
|
390
|
+
--type-h4-line-height: 1.2;
|
|
391
|
+
--type-h4-letter-spacing: -0.02em;
|
|
392
|
+
--type-h5-size: 1.5rem;
|
|
393
|
+
--type-h5-line-height: 1.2;
|
|
394
|
+
--type-h5-letter-spacing: -0.02em;
|
|
395
|
+
--type-h6-size: 1.25rem;
|
|
396
|
+
--type-h6-line-height: 1.2;
|
|
397
|
+
--type-h6-letter-spacing: -0.02em;
|
|
398
|
+
}
|
|
64
399
|
}
|
|
@@ -1,7 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
# design.md format - https://github.com/google-labs-code/design.md
|
|
3
|
+
colors:
|
|
4
|
+
primary: "#1774e0"
|
|
5
|
+
accent-cyan: "#00c1ff"
|
|
6
|
+
accent-gold: "#fec33c"
|
|
7
|
+
accent-green: "#69fea2"
|
|
8
|
+
dark: "#0d0f10"
|
|
9
|
+
surface: "#0c0d0d"
|
|
10
|
+
surface-elevated: "#0f1112"
|
|
11
|
+
surface-hover: "#191b1c"
|
|
12
|
+
subtle: "#bbc4d0"
|
|
13
|
+
typography:
|
|
14
|
+
body-default:
|
|
15
|
+
fontFamily: "Inter, system-ui, -apple-system, sans-serif"
|
|
16
|
+
fontSize: 1rem
|
|
17
|
+
fontWeight: 400
|
|
18
|
+
lineHeight: 1.6
|
|
19
|
+
label:
|
|
20
|
+
fontFamily: "Inter, system-ui, -apple-system, sans-serif"
|
|
21
|
+
fontSize: 0.875rem
|
|
22
|
+
fontWeight: 600
|
|
23
|
+
lineHeight: 1.4
|
|
24
|
+
button:
|
|
25
|
+
fontFamily: "Inter, system-ui, -apple-system, sans-serif"
|
|
26
|
+
fontSize: 0.875rem
|
|
27
|
+
fontWeight: 600
|
|
28
|
+
lineHeight: 1
|
|
29
|
+
heading-section:
|
|
30
|
+
fontFamily: "Manrope, system-ui, sans-serif"
|
|
31
|
+
fontSize: 2.625rem
|
|
32
|
+
fontWeight: 700
|
|
33
|
+
lineHeight: 1.2
|
|
34
|
+
hero-primary:
|
|
35
|
+
fontFamily: "Manrope, system-ui, sans-serif"
|
|
36
|
+
fontSize: 3.75rem
|
|
37
|
+
fontWeight: 700
|
|
38
|
+
lineHeight: 1.1
|
|
39
|
+
code-inline:
|
|
40
|
+
fontFamily: "\"Fira Code\", ui-monospace, monospace"
|
|
41
|
+
fontSize: 0.875rem
|
|
42
|
+
fontWeight: 400
|
|
43
|
+
lineHeight: 1.6
|
|
44
|
+
rounded:
|
|
45
|
+
default: 0.5rem
|
|
46
|
+
spacing:
|
|
47
|
+
section: 5rem
|
|
48
|
+
---
|
|
49
|
+
|
|
1
50
|
## OneQode Design Tokens
|
|
2
51
|
|
|
3
52
|
> Source of truth: `oneqode-design-system/build/json/tokens.json`
|
|
4
|
-
> Generated: 2026-04-22
|
|
5
53
|
> Auto-synced to `.claude-plugin/oneqode-workspace/data/design-tokens.md` on each build.
|
|
6
54
|
> If values here seem wrong, rebuild with `pnpm build:tokens` in the design system repo.
|
|
7
55
|
|
|
@@ -101,4 +149,65 @@
|
|
|
101
149
|
| --- | --- | --- | --- |
|
|
102
150
|
| shadow-dropdown | --shadow-dropdown | 0 8px 40px rgba(255, 255, 255, 0.06) | Dropdown panel shadow |
|
|
103
151
|
| shadow-avatar-glow | --shadow-avatar-glow | inset 0 11.46px 22.92px #ffffff14, inset 0 2.87px 2.87px #ffffff59 | Avatar/icon glow effect |
|
|
104
|
-
| radius | --radius | 0.5rem | Default border radius for cards and inputs |
|
|
152
|
+
| radius | --radius | 0.5rem | Default border radius for cards and inputs |
|
|
153
|
+
|
|
154
|
+
### Typography Composites
|
|
155
|
+
These are synthesized text styles - apply all three variables together for consistent, design-system-aligned typography.
|
|
156
|
+
| Style | Font Family | Font Size | Font Weight | Line Height | Use For |
|
|
157
|
+
| --- | --- | --- | --- | --- | --- |
|
|
158
|
+
| body-default | --font-sans | --font-size-body (1rem) | --font-weight-normal (400) | 1.6 | Standard paragraph and prose text |
|
|
159
|
+
| body-emphasis | --font-sans | --font-size-body (1rem) | --font-weight-medium (500) | 1.6 | Emphasized body copy, callouts |
|
|
160
|
+
| label | --font-sans | --font-size-label (0.875rem) | --font-weight-semibold (600) | 1.4 | Form labels, data values, small UI text |
|
|
161
|
+
| caption | --font-sans | --font-size-caption (0.75rem) | --font-weight-normal (400) | 1.4 | Metadata, breadcrumbs, image captions |
|
|
162
|
+
| button | --font-sans | --font-size-label (0.875rem) | --font-weight-semibold (600) | 1 | Button labels, CTA text |
|
|
163
|
+
| nav-item | --font-sans | --font-size-nav (0.9375rem) | --font-weight-medium (500) | 1.4 | Navigation links, menu items |
|
|
164
|
+
| code-inline | --font-mono | --font-size-label (0.875rem) | --font-weight-normal (400) | 1.6 | Inline code snippets, terminal output |
|
|
165
|
+
| heading-sm | --font-display | --font-size-heading-sm (1.75rem) | --font-weight-bold (700) | 1.2 | Mobile section headings, card titles |
|
|
166
|
+
| heading-section | --font-display | --font-size-heading (2.625rem) | --font-weight-bold (700) | 1.2 | Desktop section headings |
|
|
167
|
+
| hero-primary | --font-display | --font-size-hero (3.75rem) | --font-weight-bold (700) | 1.1 | Primary hero headline |
|
|
168
|
+
| display-max | --font-display | --font-size-display (4.5rem) | --font-weight-bold (700) | 1.05 | Maximum display headline, marketing hero |
|
|
169
|
+
|
|
170
|
+
### Component State Recipes
|
|
171
|
+
Token combinations for common interactive states. Use these as the canonical recipes.
|
|
172
|
+
|
|
173
|
+
| Component State | Background | Border | Text | Shadow | Notes |
|
|
174
|
+
| --- | --- | --- | --- | --- | --- |
|
|
175
|
+
| Card (default) | --color-surface | --color-line | white | none | Base card surface |
|
|
176
|
+
| Card (elevated, modal, popover) | --color-surface-elevated | --color-line | white | --shadow-dropdown | Raised above page |
|
|
177
|
+
| Card (inset/recessed) | --color-surface-inset | --color-line-faint | --color-muted | none | Inset panel inside a card |
|
|
178
|
+
| Row/item hover | --color-surface-hover | --color-line | white | none | Solid hover on list items |
|
|
179
|
+
| Overlay hover | --color-hover (overlay) | none | white | none | Translucent hover on dark bg |
|
|
180
|
+
| Badge / chip | --color-surface-badge | --color-line-faint | white | none | Status badge background |
|
|
181
|
+
| Input (default) | --color-surface | --color-line | white | none | Text input, select |
|
|
182
|
+
| Input (focus) | --color-surface | --color-primary | white | none | Replace border with primary on focus |
|
|
183
|
+
| Divider (section) | none | --color-divider | none | none | Between major page sections |
|
|
184
|
+
| Divider (soft) | none | --color-divider-soft | none | none | Between items in a list |
|
|
185
|
+
| Separator line (visible) | none | --color-line | none | none | Standard visible rule |
|
|
186
|
+
| Separator line (subtle) | none | --color-line-faint | none | none | De-emphasized rule |
|
|
187
|
+
| Success indicator | --color-accent-green (at low opacity) | none | --color-accent-green | none | Positive state, confirmation |
|
|
188
|
+
| Warning / error | --color-accent-gold (at low opacity) | none | --color-accent-gold | none | Warning badge, caution state |
|
|
189
|
+
| Primary CTA button | --color-primary | none | white | none | Main action button |
|
|
190
|
+
| Secondary / ghost button | transparent | --color-line | white | none | Less prominent action |
|
|
191
|
+
|
|
192
|
+
### Token Decision Guide
|
|
193
|
+
When to pick one token over an adjacent similar one.
|
|
194
|
+
|
|
195
|
+
**Background layers (dark to light):**
|
|
196
|
+
--color-dark-deeper (deepest) -> --color-dark-deep -> --color-dark (page bg) -> --color-surface (card) -> --color-surface-elevated (modal) -> --color-surface-inset (recessed)
|
|
197
|
+
|
|
198
|
+
**Text emphasis (high to low):**
|
|
199
|
+
white (headings) -> --color-muted (70% white, secondary) -> --color-subtle (blue-gray, tertiary) -> --color-dim (dimmed, quaternary)
|
|
200
|
+
|
|
201
|
+
**Border/line strength (strongest to faintest):**
|
|
202
|
+
--color-line (10% white, standard visible border) -> --color-line-faint (5% white, subtle) -> --color-divider (#ffffff08, section) -> --color-divider-soft (#ffffff05, barely visible)
|
|
203
|
+
|
|
204
|
+
**Hover overlays:**
|
|
205
|
+
Use --color-surface-hover (solid dark surface) when the element has a discrete background that changes.
|
|
206
|
+
Use --color-hover (translucent 5% white overlay) when layering on top of an existing dark background without replacing it.
|
|
207
|
+
Use --color-tint (2% white) for the most subtle background tint, e.g., alternating row shading.
|
|
208
|
+
|
|
209
|
+
**Accent color selection:**
|
|
210
|
+
--color-primary (#1774e0) - interactive actions, links, focus rings, primary CTAs
|
|
211
|
+
--color-accent-cyan (#00c1ff) - highlights, secondary CTAs, decorative accents
|
|
212
|
+
--color-accent-gold (#fec33c) - warnings, badges, caution states
|
|
213
|
+
--color-accent-green (#69fea2) - success, positive confirmation, online status
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneqode/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OneQode design tokens: CSS custom properties, Tailwind v4 theme, shadcn variables, and flat JSON.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,13 +33,14 @@
|
|
|
33
33
|
"./tailwind-theme.css": "./build/css/tailwind-theme.css",
|
|
34
34
|
"./shadcn-vars.css": "./build/css/shadcn-vars.css",
|
|
35
35
|
"./tokens.json": "./build/json/tokens.json",
|
|
36
|
-
"./remake.css": "./build/css/remake/tokens.css"
|
|
36
|
+
"./remake.css": "./build/css/remake/tokens.css",
|
|
37
|
+
"./recipes.css": "./build/css/recipes.css"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"style-dictionary": "^5.4.0"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
|
-
"build:tokens": "
|
|
43
|
+
"build:tokens": "node scripts/build-tokens.mjs && pnpm build:agent-ref",
|
|
43
44
|
"build:agent-ref": "node scripts/generate-agent-reference.mjs",
|
|
44
45
|
"build:docs": "cd docs && pnpm build",
|
|
45
46
|
"build": "pnpm build:tokens && pnpm build:docs",
|