@danieljoffe/shared-ui 0.0.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/LICENSE.md +117 -0
- package/README.md +373 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5360 -0
- package/dist/lib/Alert.d.ts +13 -0
- package/dist/lib/Alert.d.ts.map +1 -0
- package/dist/lib/AspectRatio.d.ts +8 -0
- package/dist/lib/AspectRatio.d.ts.map +1 -0
- package/dist/lib/Avatar.d.ts +11 -0
- package/dist/lib/Avatar.d.ts.map +1 -0
- package/dist/lib/Badge.d.ts +12 -0
- package/dist/lib/Badge.d.ts.map +1 -0
- package/dist/lib/Breadcrumb.d.ts +12 -0
- package/dist/lib/Breadcrumb.d.ts.map +1 -0
- package/dist/lib/Button.d.ts +23 -0
- package/dist/lib/Button.d.ts.map +1 -0
- package/dist/lib/CTACard.d.ts +10 -0
- package/dist/lib/CTACard.d.ts.map +1 -0
- package/dist/lib/Card.d.ts +39 -0
- package/dist/lib/Card.d.ts.map +1 -0
- package/dist/lib/Checkbox.d.ts +8 -0
- package/dist/lib/Checkbox.d.ts.map +1 -0
- package/dist/lib/Container.d.ts +10 -0
- package/dist/lib/Container.d.ts.map +1 -0
- package/dist/lib/Divider.d.ts +11 -0
- package/dist/lib/Divider.d.ts.map +1 -0
- package/dist/lib/Dropdown.d.ts +17 -0
- package/dist/lib/Dropdown.d.ts.map +1 -0
- package/dist/lib/FormFieldError.d.ts +6 -0
- package/dist/lib/FormFieldError.d.ts.map +1 -0
- package/dist/lib/Grid.d.ts +26 -0
- package/dist/lib/Grid.d.ts.map +1 -0
- package/dist/lib/GridBg.d.ts +7 -0
- package/dist/lib/GridBg.d.ts.map +1 -0
- package/dist/lib/Heading.d.ts +12 -0
- package/dist/lib/Heading.d.ts.map +1 -0
- package/dist/lib/Input.d.ts +12 -0
- package/dist/lib/Input.d.ts.map +1 -0
- package/dist/lib/Kbd.d.ts +8 -0
- package/dist/lib/Kbd.d.ts.map +1 -0
- package/dist/lib/Loading.d.ts +12 -0
- package/dist/lib/Loading.d.ts.map +1 -0
- package/dist/lib/Modal.d.ts +18 -0
- package/dist/lib/Modal.d.ts.map +1 -0
- package/dist/lib/PageContainer.d.ts +22 -0
- package/dist/lib/PageContainer.d.ts.map +1 -0
- package/dist/lib/PageLayout.d.ts +14 -0
- package/dist/lib/PageLayout.d.ts.map +1 -0
- package/dist/lib/Pagination.d.ts +11 -0
- package/dist/lib/Pagination.d.ts.map +1 -0
- package/dist/lib/ProgressBar.d.ts +15 -0
- package/dist/lib/ProgressBar.d.ts.map +1 -0
- package/dist/lib/Section.d.ts +23 -0
- package/dist/lib/Section.d.ts.map +1 -0
- package/dist/lib/SectionLabel.d.ts +9 -0
- package/dist/lib/SectionLabel.d.ts.map +1 -0
- package/dist/lib/Select.d.ts +17 -0
- package/dist/lib/Select.d.ts.map +1 -0
- package/dist/lib/Sidebar.d.ts +20 -0
- package/dist/lib/Sidebar.d.ts.map +1 -0
- package/dist/lib/Skeleton.d.ts +11 -0
- package/dist/lib/Skeleton.d.ts.map +1 -0
- package/dist/lib/Spacer.d.ts +8 -0
- package/dist/lib/Spacer.d.ts.map +1 -0
- package/dist/lib/Spinner.d.ts +13 -0
- package/dist/lib/Spinner.d.ts.map +1 -0
- package/dist/lib/Stack.d.ts +18 -0
- package/dist/lib/Stack.d.ts.map +1 -0
- package/dist/lib/StatsCard.d.ts +16 -0
- package/dist/lib/StatsCard.d.ts.map +1 -0
- package/dist/lib/StructuredData.d.ts +5 -0
- package/dist/lib/StructuredData.d.ts.map +1 -0
- package/dist/lib/Switch.d.ts +13 -0
- package/dist/lib/Switch.d.ts.map +1 -0
- package/dist/lib/Table.d.ts +25 -0
- package/dist/lib/Table.d.ts.map +1 -0
- package/dist/lib/Tabs.d.ts +17 -0
- package/dist/lib/Tabs.d.ts.map +1 -0
- package/dist/lib/Text.d.ts +12 -0
- package/dist/lib/Text.d.ts.map +1 -0
- package/dist/lib/Textarea.d.ts +10 -0
- package/dist/lib/Textarea.d.ts.map +1 -0
- package/dist/lib/ThemeProvider.d.ts +14 -0
- package/dist/lib/ThemeProvider.d.ts.map +1 -0
- package/dist/lib/ThemeToggle.d.ts +2 -0
- package/dist/lib/ThemeToggle.d.ts.map +1 -0
- package/dist/lib/Toast.d.ts +18 -0
- package/dist/lib/Toast.d.ts.map +1 -0
- package/dist/lib/Tooltip.d.ts +13 -0
- package/dist/lib/Tooltip.d.ts.map +1 -0
- package/dist/lib/index.d.ts +89 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/styles/formStyles.d.ts +42 -0
- package/dist/lib/styles/formStyles.d.ts.map +1 -0
- package/dist/lib/styles/semanticVariants.d.ts +22 -0
- package/dist/lib/styles/semanticVariants.d.ts.map +1 -0
- package/dist/lib/types.d.ts +3 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/utils/ErrorBoundary.d.ts +21 -0
- package/dist/lib/utils/ErrorBoundary.d.ts.map +1 -0
- package/dist/lib/utils/ModalErrorBoundary.d.ts +21 -0
- package/dist/lib/utils/ModalErrorBoundary.d.ts.map +1 -0
- package/dist/lib/utils/cn.d.ts +3 -0
- package/dist/lib/utils/cn.d.ts.map +1 -0
- package/dist/lib/utils/index.d.ts +5 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/validateProps.d.ts +6 -0
- package/dist/lib/utils/validateProps.d.ts.map +1 -0
- package/dist/test-setup.d.ts +1 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/package.json +79 -0
- package/src/styles/indigo-theme.css +322 -0
- package/src/styles/preview.scss +4 -0
- package/src/styles/pyre-storybook-preview.css +50 -0
- package/src/styles/pyre-theme.css +346 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
@theme {
|
|
2
|
+
/* Radius scale */
|
|
3
|
+
--radius-xs: 0.25rem;
|
|
4
|
+
--radius-sm: 0.375rem;
|
|
5
|
+
--radius-md: 0.5rem;
|
|
6
|
+
--radius-lg: 0.75rem;
|
|
7
|
+
--radius-xl: 1rem;
|
|
8
|
+
--radius-full: 9999px;
|
|
9
|
+
|
|
10
|
+
/* Fonts — actual families injected by next/font via CSS variables at runtime */
|
|
11
|
+
--font-sans: ui-sans-serif, system-ui, sans-serif;
|
|
12
|
+
--font-mono: ui-monospace, monospace;
|
|
13
|
+
|
|
14
|
+
/* Shadows */
|
|
15
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
16
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
17
|
+
--shadow-md:
|
|
18
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
19
|
+
--shadow-lg:
|
|
20
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
|
|
21
|
+
--shadow-xl:
|
|
22
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
|
23
|
+
|
|
24
|
+
/* Animation */
|
|
25
|
+
--animate-fade-in: fade-in 0.2s ease-out;
|
|
26
|
+
--animate-slide-up: slide-up 0.2s ease-out;
|
|
27
|
+
--animate-slide-down: slide-down 0.15s ease-out;
|
|
28
|
+
--animate-slide-out-down: slide-out-down 0.15s ease-in forwards;
|
|
29
|
+
--animate-scale-in: scale-in 0.15s ease-out;
|
|
30
|
+
|
|
31
|
+
/* Colors - Brand (blue-indigo, oklch hue 250) */
|
|
32
|
+
--color-brand-50: oklch(0.97 0.01 250);
|
|
33
|
+
--color-brand-100: oklch(0.93 0.03 250);
|
|
34
|
+
--color-brand-200: oklch(0.87 0.06 250);
|
|
35
|
+
--color-brand-300: oklch(0.78 0.1 250);
|
|
36
|
+
--color-brand-400: oklch(0.68 0.15 250);
|
|
37
|
+
--color-brand-500: oklch(0.54 0.19 250);
|
|
38
|
+
--color-brand-600: oklch(0.5 0.19 250);
|
|
39
|
+
--color-brand-700: oklch(0.43 0.17 250);
|
|
40
|
+
--color-brand-800: oklch(0.37 0.14 250);
|
|
41
|
+
--color-brand-900: oklch(0.3 0.1 250);
|
|
42
|
+
--color-brand-950: oklch(0.22 0.08 250);
|
|
43
|
+
|
|
44
|
+
/* Semantic Colors - Surface */
|
|
45
|
+
--color-surface: #ffffff;
|
|
46
|
+
--color-surface-secondary: #f9fafb;
|
|
47
|
+
--color-surface-tertiary: #f3f4f6;
|
|
48
|
+
--color-surface-elevated: #ffffff;
|
|
49
|
+
--color-surface-overlay: rgba(0, 0, 0, 0.5);
|
|
50
|
+
|
|
51
|
+
/* Semantic Colors - Border */
|
|
52
|
+
--color-border: #e5e7eb;
|
|
53
|
+
--color-border-secondary: #d1d5db;
|
|
54
|
+
--color-border-focus: oklch(0.54 0.19 250);
|
|
55
|
+
|
|
56
|
+
/* Semantic Colors - Text */
|
|
57
|
+
--color-text-primary: #111827;
|
|
58
|
+
--color-text-secondary: #6b7280;
|
|
59
|
+
--color-text-tertiary: #6b6b6b;
|
|
60
|
+
--color-text-inverse: #ffffff;
|
|
61
|
+
--color-text-brand: oklch(0.5 0.19 250);
|
|
62
|
+
/* Tokenized text color paired with brand-500 bg. Indigo's brand-500
|
|
63
|
+
(oklch 0.54 0.19 250) is dark enough that white reads cleanly. */
|
|
64
|
+
--color-text-on-brand: #ffffff;
|
|
65
|
+
|
|
66
|
+
/* Semantic Colors - Status */
|
|
67
|
+
--color-success: #10b981;
|
|
68
|
+
--color-success-light: #ecfdf5;
|
|
69
|
+
--color-warning: #f59e0b;
|
|
70
|
+
--color-warning-light: #fffbeb;
|
|
71
|
+
--color-error: #ef4444;
|
|
72
|
+
--color-error-light: #fef2f2;
|
|
73
|
+
--color-info: #2563eb;
|
|
74
|
+
--color-info-light: #eff6ff;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Dark mode overrides */
|
|
78
|
+
.dark {
|
|
79
|
+
--color-surface: #0f1117;
|
|
80
|
+
--color-surface-secondary: #161922;
|
|
81
|
+
--color-surface-tertiary: #1e2130;
|
|
82
|
+
--color-surface-elevated: #1a1d2b;
|
|
83
|
+
--color-surface-overlay: rgba(0, 0, 0, 0.7);
|
|
84
|
+
|
|
85
|
+
--color-border: #2a2d3a;
|
|
86
|
+
--color-border-secondary: #3a3d4a;
|
|
87
|
+
|
|
88
|
+
--color-text-primary: #f1f5f9;
|
|
89
|
+
--color-text-secondary: #94a3b8;
|
|
90
|
+
--color-text-tertiary: #8494a7;
|
|
91
|
+
--color-text-inverse: #0f1117;
|
|
92
|
+
--color-text-brand: oklch(0.65 0.19 250);
|
|
93
|
+
|
|
94
|
+
--color-success-light: #052e16;
|
|
95
|
+
--color-warning-light: #451a03;
|
|
96
|
+
--color-error-light: #450a0a;
|
|
97
|
+
--color-info-light: #172554;
|
|
98
|
+
|
|
99
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
100
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
101
|
+
--shadow-md:
|
|
102
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.2);
|
|
103
|
+
--shadow-lg:
|
|
104
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.2);
|
|
105
|
+
--shadow-xl:
|
|
106
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.2);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@keyframes fade-in {
|
|
110
|
+
from {
|
|
111
|
+
opacity: 0;
|
|
112
|
+
}
|
|
113
|
+
to {
|
|
114
|
+
opacity: 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@keyframes slide-up {
|
|
119
|
+
from {
|
|
120
|
+
opacity: 0;
|
|
121
|
+
transform: translateY(8px);
|
|
122
|
+
}
|
|
123
|
+
to {
|
|
124
|
+
opacity: 1;
|
|
125
|
+
transform: translateY(0);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@keyframes slide-down {
|
|
130
|
+
from {
|
|
131
|
+
opacity: 0;
|
|
132
|
+
transform: translateY(-8px);
|
|
133
|
+
}
|
|
134
|
+
to {
|
|
135
|
+
opacity: 1;
|
|
136
|
+
transform: translateY(0);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@keyframes slide-out-down {
|
|
141
|
+
from {
|
|
142
|
+
opacity: 1;
|
|
143
|
+
transform: translateY(0);
|
|
144
|
+
}
|
|
145
|
+
to {
|
|
146
|
+
opacity: 0;
|
|
147
|
+
transform: translateY(8px);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@keyframes bounceSubtle {
|
|
152
|
+
0%,
|
|
153
|
+
100% {
|
|
154
|
+
transform: translateY(0);
|
|
155
|
+
}
|
|
156
|
+
50% {
|
|
157
|
+
transform: translateY(-4px);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@keyframes pulseSlow {
|
|
162
|
+
0%,
|
|
163
|
+
100% {
|
|
164
|
+
opacity: 1;
|
|
165
|
+
}
|
|
166
|
+
50% {
|
|
167
|
+
opacity: 0.5;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@keyframes scale-in {
|
|
172
|
+
from {
|
|
173
|
+
opacity: 0;
|
|
174
|
+
transform: scale(0.95);
|
|
175
|
+
}
|
|
176
|
+
to {
|
|
177
|
+
opacity: 1;
|
|
178
|
+
transform: scale(1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@custom-variant dark (&:is(.dark *));
|
|
183
|
+
|
|
184
|
+
/* Base styles */
|
|
185
|
+
@layer base {
|
|
186
|
+
* {
|
|
187
|
+
@apply border-border outline-border-focus/50;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
html {
|
|
191
|
+
font-size: 16px;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
body {
|
|
195
|
+
@apply bg-surface text-text-primary antialiased;
|
|
196
|
+
font-family: var(--font-sans);
|
|
197
|
+
font-size: 16px;
|
|
198
|
+
line-height: 1.65;
|
|
199
|
+
font-weight: 400;
|
|
200
|
+
transition:
|
|
201
|
+
background-color 0.2s ease,
|
|
202
|
+
color 0.2s ease;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
h1,
|
|
206
|
+
h2,
|
|
207
|
+
h3,
|
|
208
|
+
h4,
|
|
209
|
+
h5,
|
|
210
|
+
h6 {
|
|
211
|
+
font-family: var(--font-sans);
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
color: inherit;
|
|
214
|
+
text-wrap: balance;
|
|
215
|
+
margin: 0;
|
|
216
|
+
letter-spacing: -0.025em;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
h1 {
|
|
220
|
+
font-size: 2.25rem;
|
|
221
|
+
line-height: 1.1;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
h2 {
|
|
225
|
+
font-size: 1.75rem;
|
|
226
|
+
line-height: 1.2;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
h3 {
|
|
230
|
+
font-size: 1.375rem;
|
|
231
|
+
line-height: 1.25;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
h4 {
|
|
235
|
+
font-size: 1.125rem;
|
|
236
|
+
line-height: 1.3;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
h5 {
|
|
240
|
+
font-size: 1rem;
|
|
241
|
+
line-height: 1.5;
|
|
242
|
+
font-weight: 500;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
h6 {
|
|
246
|
+
font-size: 0.875rem;
|
|
247
|
+
line-height: 1.5;
|
|
248
|
+
font-weight: 500;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
:is(h1, h2, h3, h4, h5, h6):first-child {
|
|
252
|
+
margin-top: 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
p {
|
|
256
|
+
margin-bottom: 0.5em;
|
|
257
|
+
}
|
|
258
|
+
p:last-child {
|
|
259
|
+
margin-bottom: 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Inline code only — code blocks are styled by rehype-pretty-code below */
|
|
263
|
+
code:not([data-theme]) {
|
|
264
|
+
font-family: var(--font-mono);
|
|
265
|
+
font-size: 0.875rem;
|
|
266
|
+
line-height: 1.5;
|
|
267
|
+
@apply bg-brand-50 text-brand-600 rounded px-1.5 py-0.5;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
ul:not(.prose ul),
|
|
271
|
+
ol:not(.prose ol) {
|
|
272
|
+
list-style: none;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
table {
|
|
276
|
+
width: 100%;
|
|
277
|
+
border-collapse: collapse;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
th,
|
|
281
|
+
td {
|
|
282
|
+
text-align: left;
|
|
283
|
+
padding: 0.25rem 0.75rem;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
th:first-child,
|
|
287
|
+
td:first-child {
|
|
288
|
+
padding-left: 0;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
th:last-child,
|
|
292
|
+
td:last-child {
|
|
293
|
+
padding-right: 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* Scrollbar styling */
|
|
298
|
+
::-webkit-scrollbar {
|
|
299
|
+
width: 6px;
|
|
300
|
+
height: 6px;
|
|
301
|
+
}
|
|
302
|
+
::-webkit-scrollbar-track {
|
|
303
|
+
background: transparent;
|
|
304
|
+
}
|
|
305
|
+
::-webkit-scrollbar-thumb {
|
|
306
|
+
background: var(--color-border-secondary);
|
|
307
|
+
border-radius: 3px;
|
|
308
|
+
}
|
|
309
|
+
::-webkit-scrollbar-thumb:hover {
|
|
310
|
+
background: var(--color-text-tertiary);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* Reduced motion */
|
|
314
|
+
@media (prefers-reduced-motion: reduce) {
|
|
315
|
+
*,
|
|
316
|
+
*::before,
|
|
317
|
+
*::after {
|
|
318
|
+
animation-duration: 0.01ms !important;
|
|
319
|
+
animation-iteration-count: 1 !important;
|
|
320
|
+
transition-duration: 0.01ms !important;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pyre overrides scoped to the `.pyre` class — for Storybook only.
|
|
3
|
+
*
|
|
4
|
+
* The production Pyre file (pyre-theme.css) registers its tokens via
|
|
5
|
+
* `@theme {}` at :root, which would clobber indigo's defaults in the
|
|
6
|
+
* Storybook preview where both palettes coexist. This file scopes the
|
|
7
|
+
* same token *values* under `.pyre` so the storybook decorator can flip
|
|
8
|
+
* between palettes by toggling a class on <body>.
|
|
9
|
+
*
|
|
10
|
+
* Values must stay in lockstep with pyre-theme.css's @theme block.
|
|
11
|
+
* If you change one, change both.
|
|
12
|
+
*/
|
|
13
|
+
.pyre {
|
|
14
|
+
--color-brand-50: oklch(0.97 0.05 127);
|
|
15
|
+
--color-brand-100: oklch(0.93 0.1 127);
|
|
16
|
+
--color-brand-200: oklch(0.87 0.16 127);
|
|
17
|
+
--color-brand-300: oklch(0.78 0.22 127);
|
|
18
|
+
--color-brand-400: oklch(0.72 0.26 127);
|
|
19
|
+
--color-brand-500: oklch(0.67 0.28 127);
|
|
20
|
+
--color-brand-600: oklch(0.6 0.26 127);
|
|
21
|
+
--color-brand-700: oklch(0.5 0.22 127);
|
|
22
|
+
--color-brand-800: oklch(0.4 0.17 127);
|
|
23
|
+
--color-brand-900: oklch(0.3 0.12 127);
|
|
24
|
+
--color-brand-950: oklch(0.2 0.08 127);
|
|
25
|
+
|
|
26
|
+
--color-surface: oklch(0.1 0.01 270);
|
|
27
|
+
--color-surface-secondary: oklch(0.13 0.01 270);
|
|
28
|
+
--color-surface-tertiary: oklch(0.16 0.01 270);
|
|
29
|
+
--color-surface-elevated: oklch(0.13 0.01 270);
|
|
30
|
+
--color-surface-overlay: rgba(0, 0, 0, 0.7);
|
|
31
|
+
|
|
32
|
+
--color-border: oklch(0.22 0.01 270);
|
|
33
|
+
--color-border-secondary: oklch(0.3 0.01 270);
|
|
34
|
+
--color-border-focus: oklch(0.67 0.28 127);
|
|
35
|
+
|
|
36
|
+
--color-text-primary: oklch(0.96 0.01 90);
|
|
37
|
+
--color-text-secondary: oklch(0.75 0.02 90);
|
|
38
|
+
--color-text-tertiary: oklch(0.6 0.02 90);
|
|
39
|
+
--color-text-inverse: oklch(0.1 0.01 270);
|
|
40
|
+
--color-text-brand: oklch(0.78 0.22 127);
|
|
41
|
+
|
|
42
|
+
--color-success: oklch(0.72 0.2 145);
|
|
43
|
+
--color-success-light: oklch(0.25 0.05 145);
|
|
44
|
+
--color-warning: oklch(0.78 0.18 70);
|
|
45
|
+
--color-warning-light: oklch(0.28 0.05 70);
|
|
46
|
+
--color-error: oklch(0.65 0.22 25);
|
|
47
|
+
--color-error-light: oklch(0.25 0.05 25);
|
|
48
|
+
--color-info: oklch(0.7 0.2 230);
|
|
49
|
+
--color-info-light: oklch(0.25 0.05 230);
|
|
50
|
+
}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pyre — chartreuse over neutral surfaces. Light by default; dark
|
|
3
|
+
* mode activates via the ``.dark`` class on ``<html>``, set by
|
|
4
|
+
* ``wyrdfold/state/Theme/ThemeProvider`` based on
|
|
5
|
+
* localStorage + ``prefers-color-scheme``.
|
|
6
|
+
*
|
|
7
|
+
* Originally shipped dark-only (the original docstring said "No
|
|
8
|
+
* light/dark switch — Pyre is one palette"), but the
|
|
9
|
+
* ``DarkModeToggle`` button + ``ThemeProvider`` were giving users a
|
|
10
|
+
* non-functional affordance: the toggle cycled state + flipped the
|
|
11
|
+
* ``.dark`` class on ``<html>``, but the theme had no rules scoped
|
|
12
|
+
* to ``.dark`` vs the default, so the page stayed dark regardless.
|
|
13
|
+
*
|
|
14
|
+
* Token *names* mirror indigo-theme.css exactly so the two themes
|
|
15
|
+
* stay drop-in-compatible. Token *values* differ.
|
|
16
|
+
*
|
|
17
|
+
* Color decisions:
|
|
18
|
+
* brand = chartreuse, oklch hue 127, peak chroma at L≈0.67.
|
|
19
|
+
* Same in both modes — the brand colour doesn't flip.
|
|
20
|
+
* surface = light: near-white at L≈0.98 (hue 270);
|
|
21
|
+
* dark: near-black at L≈0.10 (hue 270).
|
|
22
|
+
* text = light: near-black at L≈0.18 (≥ 14:1 over surface);
|
|
23
|
+
* dark: near-white at L≈0.96 (≥ 14:1 over surface).
|
|
24
|
+
* status = both modes use mid-lightness hues so the foreground
|
|
25
|
+
* reads at WCAG AA over the corresponding surface.
|
|
26
|
+
*
|
|
27
|
+
* For Storybook coexistence with indigo, see pyre-storybook-preview.css —
|
|
28
|
+
* that file scopes Pyre tokens under a `.pyre` class so the indigo theme
|
|
29
|
+
* can stay the default at :root.
|
|
30
|
+
*/
|
|
31
|
+
@theme {
|
|
32
|
+
/* Radius scale */
|
|
33
|
+
--radius-xs: 0.25rem;
|
|
34
|
+
--radius-sm: 0.375rem;
|
|
35
|
+
--radius-md: 0.5rem;
|
|
36
|
+
--radius-lg: 0.75rem;
|
|
37
|
+
--radius-xl: 1rem;
|
|
38
|
+
--radius-full: 9999px;
|
|
39
|
+
|
|
40
|
+
/* Fonts — actual families injected by next/font via CSS variables at runtime */
|
|
41
|
+
--font-sans: ui-sans-serif, system-ui, sans-serif;
|
|
42
|
+
--font-mono: ui-monospace, monospace;
|
|
43
|
+
|
|
44
|
+
/* Shadows — light defaults; dark mode overrides below. */
|
|
45
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
46
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
47
|
+
--shadow-md:
|
|
48
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
49
|
+
--shadow-lg:
|
|
50
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
|
51
|
+
--shadow-xl:
|
|
52
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.12), 0 8px 10px -6px rgba(0, 0, 0, 0.06);
|
|
53
|
+
|
|
54
|
+
/* Animation */
|
|
55
|
+
--animate-fade-in: fade-in 0.2s ease-out;
|
|
56
|
+
--animate-slide-up: slide-up 0.2s ease-out;
|
|
57
|
+
--animate-slide-down: slide-down 0.15s ease-out;
|
|
58
|
+
--animate-slide-out-down: slide-out-down 0.15s ease-in forwards;
|
|
59
|
+
--animate-scale-in: scale-in 0.15s ease-out;
|
|
60
|
+
|
|
61
|
+
/* Colors — Brand (chartreuse, oklch hue 127). Identical across modes. */
|
|
62
|
+
--color-brand-50: oklch(0.97 0.05 127);
|
|
63
|
+
--color-brand-100: oklch(0.93 0.1 127);
|
|
64
|
+
--color-brand-200: oklch(0.87 0.16 127);
|
|
65
|
+
--color-brand-300: oklch(0.78 0.22 127);
|
|
66
|
+
--color-brand-400: oklch(0.72 0.26 127);
|
|
67
|
+
--color-brand-500: oklch(0.67 0.28 127);
|
|
68
|
+
--color-brand-600: oklch(0.6 0.26 127);
|
|
69
|
+
--color-brand-700: oklch(0.5 0.22 127);
|
|
70
|
+
--color-brand-800: oklch(0.4 0.17 127);
|
|
71
|
+
--color-brand-900: oklch(0.3 0.12 127);
|
|
72
|
+
--color-brand-950: oklch(0.2 0.08 127);
|
|
73
|
+
|
|
74
|
+
/* Semantic Colors — Surface (light mode, near-white hue 270) */
|
|
75
|
+
--color-surface: oklch(0.99 0.005 270);
|
|
76
|
+
--color-surface-secondary: oklch(0.97 0.005 270);
|
|
77
|
+
--color-surface-tertiary: oklch(0.94 0.005 270);
|
|
78
|
+
--color-surface-elevated: oklch(1 0 0);
|
|
79
|
+
--color-surface-overlay: rgba(15, 15, 25, 0.4);
|
|
80
|
+
|
|
81
|
+
/* Semantic Colors — Border (light mode) */
|
|
82
|
+
--color-border: oklch(0.9 0.005 270);
|
|
83
|
+
--color-border-secondary: oklch(0.82 0.005 270);
|
|
84
|
+
--color-border-focus: oklch(0.55 0.28 127);
|
|
85
|
+
|
|
86
|
+
/* Semantic Colors — Text (light mode, near-black hue 270) */
|
|
87
|
+
--color-text-primary: oklch(0.18 0.01 270);
|
|
88
|
+
--color-text-secondary: oklch(0.4 0.02 270);
|
|
89
|
+
--color-text-tertiary: oklch(0.55 0.02 270);
|
|
90
|
+
--color-text-inverse: oklch(0.98 0.005 270);
|
|
91
|
+
--color-text-brand: oklch(0.4 0.22 127);
|
|
92
|
+
/* Brand-500 chartreuse over a near-black foreground clears WCAG
|
|
93
|
+
AA in both modes (foreground is the dark token; surface is
|
|
94
|
+
bright). */
|
|
95
|
+
--color-text-on-brand: oklch(0.15 0.02 127);
|
|
96
|
+
|
|
97
|
+
/* Semantic Colors — Status (light mode: mid-lightness hues
|
|
98
|
+
readable on near-white surfaces) */
|
|
99
|
+
--color-success: oklch(0.52 0.18 145);
|
|
100
|
+
--color-success-light: oklch(0.94 0.05 145);
|
|
101
|
+
--color-warning: oklch(0.6 0.16 70);
|
|
102
|
+
--color-warning-light: oklch(0.95 0.05 70);
|
|
103
|
+
--color-error: oklch(0.55 0.22 25);
|
|
104
|
+
--color-error-light: oklch(0.94 0.05 25);
|
|
105
|
+
--color-info: oklch(0.52 0.2 230);
|
|
106
|
+
--color-info-light: oklch(0.94 0.05 230);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* Dark mode overrides. ThemeProvider toggles ``.dark`` on
|
|
111
|
+
* ``<html>``; only the tokens that need to flip are repeated here
|
|
112
|
+
* (the radius / font / animation / brand-color values stay the
|
|
113
|
+
* same so a future palette tweak only happens in one place).
|
|
114
|
+
*
|
|
115
|
+
* Values match what shipped pre-fix when Pyre was dark-only — so
|
|
116
|
+
* users who land in dark mode (the typical OS default in the
|
|
117
|
+
* existing user base) get the identical palette they had before
|
|
118
|
+
* this PR. The new tokens are the light-mode defaults.
|
|
119
|
+
*/
|
|
120
|
+
.dark {
|
|
121
|
+
/* Shadows — heavier opacity values for the dark surface */
|
|
122
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
123
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
124
|
+
--shadow-md:
|
|
125
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.2);
|
|
126
|
+
--shadow-lg:
|
|
127
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.2);
|
|
128
|
+
--shadow-xl:
|
|
129
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.2);
|
|
130
|
+
|
|
131
|
+
/* Surface — near-black, hue 270 */
|
|
132
|
+
--color-surface: oklch(0.1 0.01 270);
|
|
133
|
+
--color-surface-secondary: oklch(0.13 0.01 270);
|
|
134
|
+
--color-surface-tertiary: oklch(0.16 0.01 270);
|
|
135
|
+
--color-surface-elevated: oklch(0.13 0.01 270);
|
|
136
|
+
--color-surface-overlay: rgba(0, 0, 0, 0.7);
|
|
137
|
+
|
|
138
|
+
/* Border */
|
|
139
|
+
--color-border: oklch(0.22 0.01 270);
|
|
140
|
+
--color-border-secondary: oklch(0.3 0.01 270);
|
|
141
|
+
--color-border-focus: oklch(0.67 0.28 127);
|
|
142
|
+
|
|
143
|
+
/* Text — near-white */
|
|
144
|
+
--color-text-primary: oklch(0.96 0.01 90);
|
|
145
|
+
--color-text-secondary: oklch(0.75 0.02 90);
|
|
146
|
+
--color-text-tertiary: oklch(0.6 0.02 90);
|
|
147
|
+
--color-text-inverse: oklch(0.1 0.01 270);
|
|
148
|
+
--color-text-brand: oklch(0.78 0.22 127);
|
|
149
|
+
|
|
150
|
+
/* Status (semantic hues, dimmed chroma for dark surface) */
|
|
151
|
+
--color-success: oklch(0.72 0.2 145);
|
|
152
|
+
--color-success-light: oklch(0.25 0.05 145);
|
|
153
|
+
--color-warning: oklch(0.78 0.18 70);
|
|
154
|
+
--color-warning-light: oklch(0.28 0.05 70);
|
|
155
|
+
--color-error: oklch(0.65 0.22 25);
|
|
156
|
+
--color-error-light: oklch(0.25 0.05 25);
|
|
157
|
+
--color-info: oklch(0.7 0.2 230);
|
|
158
|
+
--color-info-light: oklch(0.25 0.05 230);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@keyframes fade-in {
|
|
162
|
+
from {
|
|
163
|
+
opacity: 0;
|
|
164
|
+
}
|
|
165
|
+
to {
|
|
166
|
+
opacity: 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@keyframes slide-up {
|
|
171
|
+
from {
|
|
172
|
+
opacity: 0;
|
|
173
|
+
transform: translateY(8px);
|
|
174
|
+
}
|
|
175
|
+
to {
|
|
176
|
+
opacity: 1;
|
|
177
|
+
transform: translateY(0);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@keyframes slide-down {
|
|
182
|
+
from {
|
|
183
|
+
opacity: 0;
|
|
184
|
+
transform: translateY(-8px);
|
|
185
|
+
}
|
|
186
|
+
to {
|
|
187
|
+
opacity: 1;
|
|
188
|
+
transform: translateY(0);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes slide-out-down {
|
|
193
|
+
from {
|
|
194
|
+
opacity: 1;
|
|
195
|
+
transform: translateY(0);
|
|
196
|
+
}
|
|
197
|
+
to {
|
|
198
|
+
opacity: 0;
|
|
199
|
+
transform: translateY(8px);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@keyframes scale-in {
|
|
204
|
+
from {
|
|
205
|
+
opacity: 0;
|
|
206
|
+
transform: scale(0.95);
|
|
207
|
+
}
|
|
208
|
+
to {
|
|
209
|
+
opacity: 1;
|
|
210
|
+
transform: scale(1);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Base styles */
|
|
215
|
+
@layer base {
|
|
216
|
+
* {
|
|
217
|
+
@apply border-border outline-border-focus/50;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
html {
|
|
221
|
+
font-size: 16px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
body {
|
|
225
|
+
@apply bg-surface text-text-primary antialiased;
|
|
226
|
+
font-family: var(--font-sans);
|
|
227
|
+
font-size: 16px;
|
|
228
|
+
line-height: 1.65;
|
|
229
|
+
font-weight: 400;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
h1,
|
|
233
|
+
h2,
|
|
234
|
+
h3,
|
|
235
|
+
h4,
|
|
236
|
+
h5,
|
|
237
|
+
h6 {
|
|
238
|
+
font-family: var(--font-sans);
|
|
239
|
+
font-weight: 600;
|
|
240
|
+
color: inherit;
|
|
241
|
+
text-wrap: balance;
|
|
242
|
+
margin: 0;
|
|
243
|
+
letter-spacing: -0.025em;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
h1 {
|
|
247
|
+
font-size: 2.25rem;
|
|
248
|
+
line-height: 1.1;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
h2 {
|
|
252
|
+
font-size: 1.75rem;
|
|
253
|
+
line-height: 1.2;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
h3 {
|
|
257
|
+
font-size: 1.375rem;
|
|
258
|
+
line-height: 1.25;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
h4 {
|
|
262
|
+
font-size: 1.125rem;
|
|
263
|
+
line-height: 1.3;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
h5 {
|
|
267
|
+
font-size: 1rem;
|
|
268
|
+
line-height: 1.5;
|
|
269
|
+
font-weight: 500;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
h6 {
|
|
273
|
+
font-size: 0.875rem;
|
|
274
|
+
line-height: 1.5;
|
|
275
|
+
font-weight: 500;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
:is(h1, h2, h3, h4, h5, h6):first-child {
|
|
279
|
+
margin-top: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
p {
|
|
283
|
+
margin-bottom: 0.5em;
|
|
284
|
+
}
|
|
285
|
+
p:last-child {
|
|
286
|
+
margin-bottom: 0;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
code:not([data-theme]) {
|
|
290
|
+
font-family: var(--font-mono);
|
|
291
|
+
font-size: 0.875rem;
|
|
292
|
+
line-height: 1.5;
|
|
293
|
+
@apply bg-brand-950 text-brand-300 rounded px-1.5 py-0.5;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
ul:not(.prose ul),
|
|
297
|
+
ol:not(.prose ol) {
|
|
298
|
+
list-style: none;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
table {
|
|
302
|
+
width: 100%;
|
|
303
|
+
border-collapse: collapse;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
th,
|
|
307
|
+
td {
|
|
308
|
+
text-align: left;
|
|
309
|
+
padding: 0.25rem 0.75rem;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
th:first-child,
|
|
313
|
+
td:first-child {
|
|
314
|
+
padding-left: 0;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
th:last-child,
|
|
318
|
+
td:last-child {
|
|
319
|
+
padding-right: 0;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
::-webkit-scrollbar {
|
|
324
|
+
width: 6px;
|
|
325
|
+
height: 6px;
|
|
326
|
+
}
|
|
327
|
+
::-webkit-scrollbar-track {
|
|
328
|
+
background: transparent;
|
|
329
|
+
}
|
|
330
|
+
::-webkit-scrollbar-thumb {
|
|
331
|
+
background: var(--color-border-secondary);
|
|
332
|
+
border-radius: 3px;
|
|
333
|
+
}
|
|
334
|
+
::-webkit-scrollbar-thumb:hover {
|
|
335
|
+
background: var(--color-text-tertiary);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
@media (prefers-reduced-motion: reduce) {
|
|
339
|
+
*,
|
|
340
|
+
*::before,
|
|
341
|
+
*::after {
|
|
342
|
+
animation-duration: 0.01ms !important;
|
|
343
|
+
animation-iteration-count: 1 !important;
|
|
344
|
+
transition-duration: 0.01ms !important;
|
|
345
|
+
}
|
|
346
|
+
}
|